实体框架的Find方法是如何工作的?

问题描述 投票:0回答:3

我正在学习实体框架,并遇到了一些我无法理解的 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
  1. 为什么在调用 Include() 后第一种情况下我无法调用 Find() 方法,但可以使用Where() 和 First() ?
  2. 如果我使用 Find() 的第二种情况,这里我无法调用 Lodgings 的 Include() 方法,那么我应该如何加载相关的住宿呢?

我的问题可以用另一种方式表达:

  1. 正确的做法是什么:找到一个对象并加载所有相关的内部对象(一对多)?
  2. 正确的做法是什么:加载所有对象(集合 A)和内部相关对象(集合 A.I),然后通过 id 从(A)中找到一个?
c# entity-framework
3个回答
16
投票

重点是

Find
首先在上下文的本地缓存中进行搜索。如果未找到匹配项,则会向数据库发送查询。

DbSet 上的 Find 方法使用主键值来尝试查找 由上下文跟踪的实体。如果在 context 然后查询将被发送到数据库以查找实体 那里。如果在上下文中找不到该实体,则返回 Null,或者 在数据库中。

我认为这是内部解释,IQueryable 上没有

Find
。 当您使用以下代码时,EF 始终向数据库发送请求:

var destination = organizationDbContext.Destinations // case # 1
                .Include("Lodgings")
                .First(p=>p.DestinationId==1); 

更多信息:https://msdn.microsoft.com/en-us/data/jj573936.aspx


2
投票

问题是我们使用不同的类型,其中一种类型包含 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); 

0
投票

1- 实体框架中的Find 方法通常与主键一起使用,并且它不接受 lambda 表达式。 var 目的地 = _context.Destinations.Find(promoContent.Id);

2- 如果您需要使用主键以外的条件进行检索,则应使用FirstOrDefault或SingleOrDefault var 目的地 = _context.Destinations.FirstOrDefault(x => x.Id==promoContent.Id // && x.Name == "jack" // 这是可选的// );

© www.soinside.com 2019 - 2024. All rights reserved.