【问题标题】:C# linq to entity include with condition and orderingC# linq to entity 包括条件和排序
【发布时间】:2017-10-12 08:59:46
【问题描述】:

我有以下(简化的)设置:

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);

这不起作用。

基本上,我试图包括所有父母子女,但按 id 降序排列,然后检查第一个(例如最新的)是否有 imported == falsetimeSpan == null,并且只包括有的父行符合这个条件的孩子。

我知道我可以这样做:

var relevant = context.parent
                .include(x => x.child);

然后提取我需要的数据,但是是否可以使用 Linq 一次性完成?

【问题讨论】:

标签: c# linq linq-to-entities


【解决方案1】:

当您使用标签 linq-to-entities 我假设您使用的是实体框架。

在我看来,您在 Parent 和 Child 之间建立了一对多关系的模型:每个 Parent 都有零个或多个 Child,每个 Child 都属于一个 Parent。

也可能是你有一个多对多的关系。这些类略有不同(数据库将有一个额外的表,而您的 DbContext 中没有),但问题仍然存在。

这可能是因为您的简化,但我看到您的课程中有一些奇怪的东西可能会导致您的问题。

在实体框架中,适当的一对多关系建模如下:

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 集合不能是 List。 ChildList[3] 是什么意思?

此外,这个集合应该是虚拟的(参见SO: Understanding code first virtual properties

你写道:

基本上,我试图包括所有父母的孩子,但是为了 它们按 id 降序,然后检查是否是第一个(例如最新的) 已导入 == false 和 timeSpan == null,并且仅包含 具有满足此条件的子行的父行。

有点难以理解,但似乎你有一个父母序列,你只想要那些父母和他们的孩子,其中具有最高 ChildId 的孩子没有被导入并且有一个空的 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));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-20
    • 1970-01-01
    • 2011-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多