我正在学习实体框架,并遇到了一些我无法理解的 Find() 方法。
示例取自 Julia Lerman 《编程实体框架:代码优先》一书
public class Destination
{
public int DestinationId { get; set; }
public string Name { get; set; }
public string Country { get; set; }
public string Description { get; set; }
public byte?[] Photo { get; set; }
public ICollection<Lodging> Lodgings { get; set; }
public Destination()
{
Lodgings = new List<Lodging>();
}
}
public class Lodging
{
public int LodgingId { get; set; }
public string Name { get; set; }
public string Owner { get; set; }
public bool IsResort { get; set; }
public Destination Destination { get; set; }
}
我通过以下方式处理数据:
var destination = organizationDbContext.Destinations // case # 1
.Include("Lodgings")
.First(p=>p.DestinationId==1);
var destination = organizationDbContext.Destinations.Find(1); // case # 2
我的问题可以用另一种方式表达:
重点是
Find
首先在上下文的本地缓存中进行搜索。如果未找到匹配项,则会向数据库发送查询。
DbSet 上的 Find 方法使用主键值来尝试查找 由上下文跟踪的实体。如果在 context 然后查询将被发送到数据库以查找实体 那里。如果在上下文中找不到该实体,则返回 Null,或者 在数据库中。
我认为这是内部解释,IQueryable 上没有
Find
。
当您使用以下代码时,EF 始终向数据库发送请求:
var destination = organizationDbContext.Destinations // case # 1
.Include("Lodgings")
.First(p=>p.DestinationId==1);
问题是我们使用不同的类型,其中一种类型包含 Find 方法,而另一种则不包含:
1.
var destination = organizationDbContext.Destinations // case # 1
.Include("Lodgings") // type here is IQueryable<T> no method Find defined
.First(p=>p.DestinationId==1);
2.
// type here is DbSet<T> with defined method Find
var destination = organizationDbContext.Destinations.Find(1);
1- 实体框架中的Find 方法通常与主键一起使用,并且它不接受 lambda 表达式。 var 目的地 = _context.Destinations.Find(promoContent.Id);
2- 如果您需要使用主键以外的条件进行检索,则应使用FirstOrDefault或SingleOrDefault var 目的地 = _context.Destinations.FirstOrDefault(x => x.Id==promoContent.Id // && x.Name == "jack" // 这是可选的// );