C# 是否可以重写复杂的EF核心;。包括「;呼吁「;加入;电话?

C# 是否可以重写复杂的EF核心;。包括「;呼吁「;加入;电话?,c#,linq,asp.net-core,entity-framework-core,C#,Linq,Asp.net Core,Entity Framework Core,我有两个名为Service和ServiceBranch的EF核心实体模型: public class Service { public Guid ID { get; set; } public Guid? ParentServiceID { get; set; } // foreign key to the same table public string Name { get; set; } public DateTime? DateDeleted { get;

我有两个名为Service和ServiceBranch的EF核心实体模型:

public class Service
{
    public Guid ID { get; set; }
    public Guid? ParentServiceID { get; set; } // foreign key to the same table
    public string Name { get; set; }
    public DateTime? DateDeleted { get; set; }

    public virtual ICollection<Service> InverseParent { get; set; } // navigation property
    public virtual ICollection<ServiceBranch> ServiceBranches { get; set; } // navigation property
}

public class ServiceBranch
{
    public Guid ID { get; set; }
    public Guid ServiceID { get; set; } // foreign key
    public string Name { get; set; }
    public DateTime? DateDeleted { get; set; }

    public virtual Service Service { get; set; } // navigation property
}
我想重写我的查询,以便使用“join”而不是“.Include”,类似这样:

var serviceEntity = _context.Set<Service>().Where(x => x.ID == neededID && x.DateDeleted == null)
                .Include(x => x.ServiceBranches)
                .Include(x => x.InverseParent)
                    .ThenInclude(InverseParent => InverseParent.ServiceBranches)
                .FirstOrDefault();
var serviceEntity = from service in _context.Set<Service>()
                where service.ID == neededID && service.DateDeleted == null
                join branches in _context.Set<ServiceBranch>() on service.ID equals branches.ServiceID
                where branches.DateDeleted == null // filter which I cannot use with .Include-s
                let // whatever, can't make it work
                select // etc
var serviceEntity = _context.Set<Service>()
    .Where(x => x.ID == neededID && x.DateDeleted == null)
    .Select(x => new // you can make this a named type if necessary
        {
           Service = x,
           ActiveBranches = x.ServiceBranches.Where(b => b.DateDeleted == null),
           InverseParent,
           InverseParentServiceBranches = x.InverseParent.ServiceBranches
        })
    .FirstOrDefault();
var serviceEntity=来自_context.Set()中的服务
其中service.ID==needId&&service.DateDeleted==null
在service.ID上的_context.Set()中连接分支等于branchs.ServiceID
其中branchs.DateDeleted==null//无法与.Include-s一起使用的筛选器
不管怎样,我都不能让它工作
选择//等

我不知道如何重写它。或者甚至可以通过连接来实现。Include将加载的对象直接放在实体框架模型上,该模型实际上应该直接表示数据库中的内容。如果您想要一个过滤的集合,我建议您使用一个不同的模型来表示您试图表示的内容,然后使用Select来投影到该模型。大概是这样的:

var serviceEntity = _context.Set<Service>().Where(x => x.ID == neededID && x.DateDeleted == null)
                .Include(x => x.ServiceBranches)
                .Include(x => x.InverseParent)
                    .ThenInclude(InverseParent => InverseParent.ServiceBranches)
                .FirstOrDefault();
var serviceEntity = from service in _context.Set<Service>()
                where service.ID == neededID && service.DateDeleted == null
                join branches in _context.Set<ServiceBranch>() on service.ID equals branches.ServiceID
                where branches.DateDeleted == null // filter which I cannot use with .Include-s
                let // whatever, can't make it work
                select // etc
var serviceEntity = _context.Set<Service>()
    .Where(x => x.ID == neededID && x.DateDeleted == null)
    .Select(x => new // you can make this a named type if necessary
        {
           Service = x,
           ActiveBranches = x.ServiceBranches.Where(b => b.DateDeleted == null),
           InverseParent,
           InverseParentServiceBranches = x.InverseParent.ServiceBranches
        })
    .FirstOrDefault();
var serviceEntity=\u context.Set()
.Where(x=>x.ID==neededID&&x.DateDeleted==null)
.Select(x=>new//如果需要,可以将其设置为命名类型
{
服务=x,
ActiveBranchs=x.ServiceBranchs.Where(b=>b.DateDeleted==null),
反向分离,
InverseParentServiceBranchs=x.InverseParent.ServiceBranchs
})
.FirstOrDefault();

Include
将加载的对象直接放在实体框架模型上,该模型实际上应该直接表示数据库中的内容。如果您想要一个过滤的集合,我建议您使用一个不同的模型来表示您试图表示的内容,然后使用Select来投影到该模型。大概是这样的:

var serviceEntity = _context.Set<Service>().Where(x => x.ID == neededID && x.DateDeleted == null)
                .Include(x => x.ServiceBranches)
                .Include(x => x.InverseParent)
                    .ThenInclude(InverseParent => InverseParent.ServiceBranches)
                .FirstOrDefault();
var serviceEntity = from service in _context.Set<Service>()
                where service.ID == neededID && service.DateDeleted == null
                join branches in _context.Set<ServiceBranch>() on service.ID equals branches.ServiceID
                where branches.DateDeleted == null // filter which I cannot use with .Include-s
                let // whatever, can't make it work
                select // etc
var serviceEntity = _context.Set<Service>()
    .Where(x => x.ID == neededID && x.DateDeleted == null)
    .Select(x => new // you can make this a named type if necessary
        {
           Service = x,
           ActiveBranches = x.ServiceBranches.Where(b => b.DateDeleted == null),
           InverseParent,
           InverseParentServiceBranches = x.InverseParent.ServiceBranches
        })
    .FirstOrDefault();
var serviceEntity=\u context.Set()
.Where(x=>x.ID==neededID&&x.DateDeleted==null)
.Select(x=>new//如果需要,可以将其设置为命名类型
{
服务=x,
ActiveBranchs=x.ServiceBranchs.Where(b=>b.DateDeleted==null),
反向分离,
InverseParentServiceBranchs=x.InverseParent.ServiceBranchs
})
.FirstOrDefault();

在这种特殊情况下,您不需要联接,而是包含所需的
服务
实体及其所有子实体的平面列表。一般来说,这需要递归查询(LINQ/EF核心不支持),但对于单级来说,这是一个类似于过滤器的简单问题

service.ID == neededID || service.ParentServiceID == neededID
然后可以应用附加的
DateDeleted
标准。最后,要使用
DateDeleted
过滤器获取相关的
ServiceBranch
实体,而不是
Include
,只需使用投影(
Select

在处理返回的数据时,请使用投影实体并忽略其导航属性。e、 g

var itemsToUpdate = _context.Set<Service>()
    .Where(service => (service.ID == neededID || service.ParentServiceID == neededID)
        && service.DateDeleted == null)
    .Select(service => new
    {
        Service = service,
        ServiceBrances = service.ServiceBranches
            .Where(branch => branch.DateDeleted == null),
    });

foreach (var item in itemsToUpdate)
{
    item.Service.DateDeleted = DateTime.Now;
    foreach (var branch in item.ServiceBrances)
        branch.DateDeleted =  DateTime.Now;
}
var itemsToUpdate=\u context.Set()
.Where(service=>(service.ID==neededID | | service.ParentServiceID==neededID)
&&service.DateDeleted==null)
.选择(服务=>新建)
{
服务=服务,
ServiceBrances=service.ServiceBrances
.Where(branch=>branch.DateDeleted==null),
});
foreach(itemsToUpdate中的var项)
{
item.Service.DateDeleted=DateTime.Now;
foreach(item.ServiceBranches中的var分支)
branch.DateDeleted=DateTime.Now;
}

在这种特殊情况下,您不需要联接,而是包含所需的
服务
实体及其所有子实体的平面列表。一般来说,这需要递归查询(LINQ/EF核心不支持),但对于单级来说,这是一个类似于过滤器的简单问题

service.ID == neededID || service.ParentServiceID == neededID
然后可以应用附加的
DateDeleted
标准。最后,要使用
DateDeleted
过滤器获取相关的
ServiceBranch
实体,而不是
Include
,只需使用投影(
Select

在处理返回的数据时,请使用投影实体并忽略其导航属性。e、 g

var itemsToUpdate = _context.Set<Service>()
    .Where(service => (service.ID == neededID || service.ParentServiceID == neededID)
        && service.DateDeleted == null)
    .Select(service => new
    {
        Service = service,
        ServiceBrances = service.ServiceBranches
            .Where(branch => branch.DateDeleted == null),
    });

foreach (var item in itemsToUpdate)
{
    item.Service.DateDeleted = DateTime.Now;
    foreach (var branch in item.ServiceBrances)
        branch.DateDeleted =  DateTime.Now;
}
var itemsToUpdate=\u context.Set()
.Where(service=>(service.ID==neededID | | service.ParentServiceID==neededID)
&&service.DateDeleted==null)
.选择(服务=>新建)
{
服务=服务,
ServiceBrances=service.ServiceBrances
.Where(branch=>branch.DateDeleted==null),
});
foreach(itemsToUpdate中的var项)
{
item.Service.DateDeleted=DateTime.Now;
foreach(item.ServiceBranches中的var分支)
branch.DateDeleted=DateTime.Now;
}

关于筛选的包含,有无数的问题,尽管它还不受支持。你应该能在他们中的许多人身上找到工作。提示:不要加入。使用与“包含”相同的导航属性。虽然“过滤的包含”还不受支持,但仍有无数关于它的问题。你应该能在他们中的许多人身上找到工作。提示:不要加入。使用与Include相同的导航属性。因此,使用联接毕竟是错误的方向。感谢加入毕竟是错误的方向。谢谢