C# linq to 实体包含条件和排序
C# linq to entity include with condition and ordering
我有以下(简化的)设置:
Public class parent
{
public string name{get;set;}
public list<child> childList {get;set;}
}
Public class child
{
public int id {get;set;}
public bool imported{get;set;}
public dateTime? timeSpan {get;set;}
}
我有这个查询:
var relevant = context.parent
.include(x => x.child.OrderByDescending(y => y.id).FirstOrDefaultAsync(z => z.imported == false && timeSpan == null)
.Where(x => x.child != null);
这是行不通的。
基本上,我试图包括所有 parents children,但按 id 降序排列它们,然后检查第一个(例如最新的)是否有 imported == false
和 timeSpan == null
,并且只包括 parent 行 child 满足此条件。
我知道我可以做到:
var relevant = context.parent
.include(x => x.child);
然后提取我需要的数据,但是可以使用 Linq 一次完成吗?
由于您正在使用标签 linq-to-entities 我假设您正在使用 entity framework.
在我看来,您在 Parent 和 Child 之间建立了一个 one-to-many 关系模型:每个 Parent 都有零个或多个 Children,每个 Child 正好属于一个 Parent.
也可能是你们有many-to-many关系。 类 略有不同(数据库将有一个你在 DbContext 中没有的额外 table),但问题仍然存在。
这可能是因为你的简化,但我在你的 类 中看到一些奇怪的东西可能会导致你的问题。
在entity framework中,正确的one-to-many关系建模如下:
public class Parent
{
public int Id {get;set;}
public string name{get;set;}
// Every parent has zero or more Children
public virtual ICollection<Child> Children {get;set;}
}
public class Child
{
public int id {get;set;}
public bool Imported{get;set;}
public DateTime? TimeSpan {get;set;}
// every Child belongs to exactly one Parent using foreign key
public int ParentId {get; set;}
public Parent Parent {get; set;}
}
你的Parent中Children的collection不能是List。 ChildList[3] 是什么意思?
此外,这个Collection应该是虚拟的(参见SO: Understanding code first virtual properties)
您写道:
Basically, I am trying to include all the parents children, but order
them by id descending and then check if the first one (eg newest one)
has imported == false and timeSpan == null, and only include the
parent rows that have a child that meets this condition.
有点难理解,但看起来你有一个 Parent 序列,你只想要那些 Parent 和它们的 children,其中 [=具有最高 ChildId 的 40=] 未导入且具有空 TimeSpan。
var result = dbContext.Parents
.Select(parent => new
{
// Take all Parent properties you need in your end result, for example
Id = parent.Id,
Name = parent.Name,
Children = parent.Children
.OrderByDescending(child => child.Id),
})
.Select(parent => new
{
Id = parent.Id,
Name = parent.Name,
Children = parent.Childrent,
NewestChild = parent.Children.FirstOrDefault(),
})
// keep only the parents you want to keep:
.Where(parent => parent.NewestChild != null
&& !parent.NewestChild.Imported
&& parent.NewestChild.TimeSpan == null));
我有以下(简化的)设置:
Public class parent
{
public string name{get;set;}
public list<child> childList {get;set;}
}
Public class child
{
public int id {get;set;}
public bool imported{get;set;}
public dateTime? timeSpan {get;set;}
}
我有这个查询:
var relevant = context.parent
.include(x => x.child.OrderByDescending(y => y.id).FirstOrDefaultAsync(z => z.imported == false && timeSpan == null)
.Where(x => x.child != null);
这是行不通的。
基本上,我试图包括所有 parents children,但按 id 降序排列它们,然后检查第一个(例如最新的)是否有 imported == false
和 timeSpan == null
,并且只包括 parent 行 child 满足此条件。
我知道我可以做到:
var relevant = context.parent
.include(x => x.child);
然后提取我需要的数据,但是可以使用 Linq 一次完成吗?
由于您正在使用标签 linq-to-entities 我假设您正在使用 entity framework.
在我看来,您在 Parent 和 Child 之间建立了一个 one-to-many 关系模型:每个 Parent 都有零个或多个 Children,每个 Child 正好属于一个 Parent.
也可能是你们有many-to-many关系。 类 略有不同(数据库将有一个你在 DbContext 中没有的额外 table),但问题仍然存在。
这可能是因为你的简化,但我在你的 类 中看到一些奇怪的东西可能会导致你的问题。
在entity framework中,正确的one-to-many关系建模如下:
public class Parent
{
public int Id {get;set;}
public string name{get;set;}
// Every parent has zero or more Children
public virtual ICollection<Child> Children {get;set;}
}
public class Child
{
public int id {get;set;}
public bool Imported{get;set;}
public DateTime? TimeSpan {get;set;}
// every Child belongs to exactly one Parent using foreign key
public int ParentId {get; set;}
public Parent Parent {get; set;}
}
你的Parent中Children的collection不能是List。 ChildList[3] 是什么意思?
此外,这个Collection应该是虚拟的(参见SO: Understanding code first virtual properties)
您写道:
Basically, I am trying to include all the parents children, but order them by id descending and then check if the first one (eg newest one) has imported == false and timeSpan == null, and only include the parent rows that have a child that meets this condition.
有点难理解,但看起来你有一个 Parent 序列,你只想要那些 Parent 和它们的 children,其中 [=具有最高 ChildId 的 40=] 未导入且具有空 TimeSpan。
var result = dbContext.Parents
.Select(parent => new
{
// Take all Parent properties you need in your end result, for example
Id = parent.Id,
Name = parent.Name,
Children = parent.Children
.OrderByDescending(child => child.Id),
})
.Select(parent => new
{
Id = parent.Id,
Name = parent.Name,
Children = parent.Childrent,
NewestChild = parent.Children.FirstOrDefault(),
})
// keep only the parents you want to keep:
.Where(parent => parent.NewestChild != null
&& !parent.NewestChild.Imported
&& parent.NewestChild.TimeSpan == null));