C#linq to entity包括条件和排序

时间:2017-10-12 08:59:47

标签: c# linq linq-to-entities

我有以下(简化)设置:

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进行一次吗?

1 个答案:

答案 0 :(得分:1)

As you are using the tag linq-to-entities I assume you are using entity framework.

It seems to me that you have modeled a one-to-many relation between Parent and Child: every Parent has zero or more Children, and every Child belongs to exactly one Parent.

It could also be that you have a many-to-many relation. The classes are slightly different (and the database will have an extra table that you don't have in your DbContext), but the problem remains the same.

It could be because of your simplifications, but I see some odd things in your classes that might cause your problems.

In entity framework a proper one-to-many relation is modelled as follows:

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

The collection of Children in your Parent can't be a List. What would ChildList[3] mean?

Besides, this Collection should be virtual (See SO: Understanding code first virtual properties)

You wrote:

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.

A bit difficult to understand, but it seems that you have a sequence of Parents, and you want only those Parents and their children, where the Child with the highest ChildId is not Imported and has a null 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));