在获取父实体 EFCore 时加载子实体
Posted
技术标签:
【中文标题】在获取父实体 EFCore 时加载子实体【英文标题】:Load child entity on the fetch of the Parent entity EFCore 【发布时间】:2020-01-08 04:00:16 【问题描述】:我有以下型号。在使用 find 方法从数据库中获取时,用子实体加载父实体的更好方法是什么?
父实体:
public class Client
public int Id get; set;
public string LastName get; set;
public string Gender get; set;
public DateTime DateOfBirth get; set;
public Address Address get; set;
子实体:
public class Address
public int Id get; set;
public string FirstLine get; set;
public string SecondLine get; set;
public string Province get; set;
现在,当我尝试使用 Find 方法获取数据时,我的地址实体为空,但是当我签入 DB 数据时,该 ID 也存在于 Child 表中。
referenceContext.Clients.Find(client.Id);
有没有办法克服这个问题?当我获取父对象的同时,子实体的值也与父对象一起加载。
注意:到目前为止,如果我使用 Include(i => i.Address)
然后,然后,只有我能够加载子实体。
我已经使用了包含,但是如果我得到父实体,是否还有其他选项可以加载子实体。
referenceContext.Clients.Where(c => c.IsActive.Equals(true))
.Include(i => i.Address).ToList();
【问题讨论】:
【参考方案1】:在 EF 中,有一个名为 Eager Loading
的概念使用 .Include
。
MS Docs - Loading Related Data - EF Core
.NET Fiddle
using MyContext context = new MyContext();
IList<Client> clients =
context.Clients
.Include(c => c.Address)
.Where(c => c.LastName == "patel")
.ToList();
【讨论】:
我忘了添加这个:使用 Microsoft.EntityFrameworkCore;【参考方案2】:如你所说:
注意:到目前为止,如果我使用了 Include(i => i.Address),那么只有我能够加载子实体。
是的!这是在 EF Core 中加载相关数据的最佳方式。
你又说:
我已经使用了 Include,但是如果我得到父实体,是否还有其他选项可以加载子实体。
是的!有!这称为Lazy loading。要启用延迟加载,您必须将导航属性设置为虚拟,如下所示:
public class Client
public int Id get; set;
public string LastName get; set;
public string Gender get; set;
public DateTime DateOfBirth get; set;
public virtual Address Address get; set; // <-- Here it is
您必须按如下方式注册您的DbConext
:
services.AddDbContext<BloggingContext>(
b => b.UseLazyLoadingProxies() // <-- Here is it is
.UseSqlServer(myConnectionString));
UseLazyLoadingProxies()
方法在 Microsoft.EntityFrameworkCore.Proxies nuget 包中可用。
注意:您不能为某个查询禁用延迟加载。所以使用Eager loading是在EF Core中加载相关数据的最佳方式。
【讨论】:
【参考方案3】:您可以使用Include()
Linq 查询
using (var context = new DBEntities())
var result = (from c in context.Client.Include("Address")
where c.IsActive
select c).ToList();
Lambda 表达式
using (var context = new DBEntities())
var result = context.Client.Include(p => p.Address).Where(c => c.IsActive).ToList();
【讨论】:
以上是关于在获取父实体 EFCore 时加载子实体的主要内容,如果未能解决你的问题,请参考以下文章
elementUIel-tree搜索时加载子节点对应父节点父节点对应子节点树
elementUIel-tree搜索时加载子节点对应父节点父节点对应子节点树