猿问

使用 EFCore 检索集合时,为什么检索到的实体不包括它们与其他对象的关系?

在将 Entity Framework Core 与 SQL Server 一起使用时,我遇到了一个意想不到的问题。我有一个实体 A 与实体 B 具有一对多关系。


 [Table("client")]

    public class Client

    {

        public long ID { get; set; }

        public string Name { get; set; }


        public ICollection<Configuration> Configurations { get; set; } = new LinkedList<Configuration>();

    }

我从数据库中得到实体 A 的实例列表,如下所示:


public ICollection<Client> GetAllClients()

{

    return _dbContext.Clients.ToList();

}

当我调用这个函数时,我得到一个实例列表,关系中没有实体 B 的实例。为什么没有正确检索到关系中的对象?


我还发现,如果我将这行代码添加到函数中,就会按预期检索实体。


public ICollection<Client> GetAllClients()

{

    var test = _dbContext.Configurations.ToList();

    return _dbContext.Clients.ToList();

}

这对我来说毫无意义。我在这里错过了什么?


噜噜哒
浏览 167回答 2
2回答

catspeake

您可以使用 Include 方法指定要包含在查询结果中的相关数据(预加载)。看看下面的例子:public ICollection<Client> GetAllClients(){&nbsp; &nbsp; return _dbContext.Clients.Include(x => x.Configurations).ToList();}您可以查看MSDN 参考资料。

白衣非少年

相关的引用/集合属性必须预先加载或显式加载。您通常希望使用以下方式急切加载Include:var&nbsp;clients&nbsp;=&nbsp;await&nbsp;_context.Clients.Include(x&nbsp;=>&nbsp;x.Configurations).ToListAsync();或者,您可以延迟加载,但这通常不是一个好主意,因为它会导致 N+1 查询问题(即您发出一个查询,然后在迭代时对每个项目进行单独的附加查询,这显然效率很低).&nbsp;无论如何,延迟加载需要两件事:引用/集合属性必须具有virtual关键字。EF 通过创建实体类的动态代理并覆盖属性 getter 来添加延迟加载功能。当然,覆盖只能在虚拟机上进行。您必须显式添加延迟加载服务:services.AddDbContext<MyContext>(o&nbsp;=>&nbsp;o.UseLazyLoadingProxies() &nbsp;&nbsp;&nbsp;&nbsp;.UseSqlServer(connectionString));它在您查询配置时也有效,因为 EF 具有对象修复。换句话说,如果它之前已经检索到这些对象并将它们放在对象缓存中,它将自动填充相关的引用/集合属性。否则,如果您不以其他方式加载关系,该属性将保持为空。
随时随地看视频慕课网APP
我要回答