简体   繁体   English

如何根据子表列过滤LINQ查询?

[英]How to filter LINQ query based on child table column?

I am joining 2 tables using entity framework as mentioned in below code and want to filter data on the basis of child table column but when I run the code It is sending Table 2 as empty array. 我正在使用下面的代码中提到的实体框架连接2个表,并希望基于子表列过滤数据,但是当我运行代码时,它会将表2作为空数组发送。 While debugging the code I found below error. 在调试代码时,我发现以下错误。

Error = Unable to evaluate the expression. 错误=无法计算表达式。 Operation not supported. 不支持该操作。 Unknown error: 0x80070057. 未知错误:0x80070057。

context.Table1
    .GroupJoin(context.Table2, a => a.id, b => b.id, (a, b) => new SampleDTO
    {
        OutletCd = a.id,
        Name = a.Name,
        AddrLine1 = a.AddrLine1,
        AddrLine2 = a.AddrLine2,
        City = a.City,
        Zip = a.Zip,
        StateCd = a.StateCd,
        CtryCd = a.CtryCd,
        Country = a.Country,
        Phone = a.Phone,
        Table2 = b.Select(bd => new SampleDetails { Col1 = bd.Col1, Col2 = bd.Col2 })
            .Where(c => c.Col1.Equals("ABC"))
    })

Something arround these lines should work. 这些线周围的东西应该起作用。

context.Table1
    .Join(Table2, a => a.id, b => b.id, (a, b) => {Table1 = a, Table2 = b})
    .Where(ab => ab.Table2.Col1.Equals("ABC"))
    .Select(ab => {
        OutletCd = ab.Table1.id,
        Name = ab.Table1.Name,
        AddrLine1 = ab.Table1.AddrLine1,
        AddrLine2 = ab.Table1.AddrLine2,
        City = ab.Table1.City,
        Zip = ab.Table1.Zip,
        StateCd = ab.Table1.StateCd,
        CtryCd = ab.Table1.CtryCd,
        Country = ab.Table1.Country,
        Phone = ab.Table1.Phone,
    });

As EntityFramework works with queryables it tries to construct a query out of the select, where, orderby, ... statements. 当EntityFramework与queryables一起使用时,它尝试从select,where,orderby,...语句之外构造查询。 However your nested select is not supported and cannot be translated to a query. 但是,不支持您的嵌套选择,并且不能将其转换为查询。

Okay, I've never tried this...so I'm not totally sure without creating a POC, which I don't have time to create at the moment...but your select should only be "one query"...not an internal query inside the first Select...so something like this (assuming you can create sub-objects with object-initializers inside a Select: 好的,我从未尝试过...所以我不确定是否创建POC,目前还没有时间创建POC,但是您的选择只能是“一个查询”。而不是第一个Select内部的内部查询...所以类似这样(假设您可以在Select内部使用对象初始化器创建子对象:

var result = context.Table1.Include( a => a.b )
    .Where( a => a.b.Col1.Equals("ABC")
    .Select( x => new SampleDto {
        OutletCd = a.id,
        //other cols
        Table2 = new SampleDetails {
            Col1 = b.Col1,
            Col2 = b.Col2
        }
    });

EDIT - No Foreign Key If you don't have a foreign-key/primary-key relationship to link on, then you must completely separate your queries. 编辑-没有外键如果您没有要链接的外键/主键关系,则必须完全分开查询。 To my knowledge, your first query has to completely close (eg by calling .ToList()) before EF can run a second query. 据我所知,您的第一个查询必须完全关闭(例如,通过调用.ToList()),然后EF才能运行第二个查询。

var results = context.Table1
    .Where( a => a.b.Col1.Equals("ABC")
    .Select( x => new SampleDto {
        OutletCd = a.id,
        //other cols
    })
    .ToList();

foreach( var sampleDto in results ) {
    sampleDto.Table2 = context.Table2.Where( x => x.Condition ).ToList();
}

Apparently the elements in table2 have properties Col1 and Col2. 显然,表2中的元素具有属性Col1和Col2。 Are you certain that property Col1 is of a string type? 您确定属性Col1是字符串类型吗?

If not, then Col1.Equals(string) will use Object.Equals(object), which is always false, because Col1 is not a string. 如果不是,则Col1.Equals(string)将使用Object.Equals(object),该值始终为false,因为Col1不是字符串。

The reason you made this error is because of your method of variable naming. 出现此错误的原因是由于变量命名方法的原因。 There is no clue at all to see what kine of elements a, b, c, db are. 根本看不出元素a,b,c,db是什么种类的线索。

Because of your abstract table1 it is already difficult to see what every variable means, so let's assume that Table1 is aa table of Teachers and Table2 is a table of Students, 由于您的抽象table1已经很难理解每个变量的含义,因此假设Table1是Teachers表,而Table2是Student表,

The GroupJoin would be much easier to read if you'd use proper variable names: 如果您使用适当的变量名,GroupJoin将更容易阅读:

// groupjoin teachers and students:
var result = context.Teachers.GroupJoin(context.Students, 
    teacher => teacher.Id,             // from each Teacher take the Id
    student => student.TeacherId,      // from each Student take the teacherId

    // when they match, group the teacher and all his matching students:
    (teacher, students) => new 
    {                          // make a new object:
                               // get some Teacher properties
         Name = Teacher.Name,
         AddrLine1 = Teacher.AddrLine1,
         ...

         // make a table from the columns from all the Teacher's students:
         Table2 = students 
            .Select(student => new
            {
                Col1 = student.Col1,
                Col2 = student.Col2,
            })      
            // here it is clearly to see that Col1 comes from Student
            // I don't want all students, only those with ABC for Col1, so:
            .Where(studentColumns => studentColumns.Col1.Equals("ABC"));

Result: if the Col1 of a Student is not a string, then Table2 will remain empty 结果:如果学生的Col1不是字符串,则Table2将保持为空

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM