C# 如何基于子表列过滤LINQ查询?
我正在使用下面代码中提到的实体框架连接两个表,并希望根据子表列筛选数据,但当我运行代码时,它将表2作为空数组发送。调试代码时,我发现以下错误 错误=无法计算表达式。不支持此操作。 未知错误:0x80070057C# 如何基于子表列过滤LINQ查询?,c#,entity-framework,linq,C#,Entity Framework,Linq,我正在使用下面代码中提到的实体框架连接两个表,并希望根据子表列筛选数据,但当我运行代码时,它将表2作为空数组发送。调试代码时,我发现以下错误 错误=无法计算表达式。不支持此操作。 未知错误:0x80070057 这些线周围的东西应该有用 context.Table1 .Join(Table2, a => a.id, b => b.id, (a, b) => {Table1 = a, Table2 = b}) .Where(ab => ab.Table2.C
这些线周围的东西应该有用
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,
});
当EntityFramework使用queryables时,它尝试从select、where、orderby、。。。声明。但是,不支持嵌套的select,并且无法将其转换为查询。这些行周围的内容应该可以工作
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,
});
当EntityFramework使用queryables时,它尝试从select、where、orderby、。。。声明。但是,您的嵌套选择不受支持,无法转换为查询。好的,我从来没有尝试过这一点…因此,如果不创建POC,我不能完全确定,我现在没有时间创建POC…但是您的选择应该仅是“一个查询”…而不是第一个选择中的内部查询…所以类似这样的事情(假设您可以在选择中使用对象初始值设定项创建子对象:
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
}
});
编辑-无外键
如果没有要链接的外键/主键关系,则必须完全分离查询。据我所知,在EF可以运行第二个查询之前,第一个查询必须完全关闭(例如,通过调用.ToList())
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();
}
好的,我从来没有尝试过这个…所以如果不创建POC,我不能完全确定,我现在没有时间创建POC…但是您的select应该只是“一个查询”…而不是第一个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
}
});
编辑-无外键
如果没有要链接的外键/主键关系,则必须完全分离查询。据我所知,在EF可以运行第二个查询之前,第一个查询必须完全关闭(例如,通过调用.ToList())
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();
}
显然,表2中的元素具有属性Col1和Col2。您确定属性Col1是字符串类型吗 如果不是,那么Col1.Equals(string)将使用Object.Equals(Object),这总是false,因为Col1不是字符串 你犯这个错误的原因是因为你的变量命名方法。根本不知道元素a,b,c,db是什么 由于您的抽象表1,已经很难看到每个变量的含义,因此假设表1是教师表,表2是学生表 如果使用适当的变量名,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"));
结果:如果学生的Col1不是字符串,那么表2中的元素将保持为空显然,表2中的元素具有属性Col1和Col2。您确定属性Col1是字符串类型吗 如果不是,那么Col1.Equals(string)将使用Object.Equals(Object),这总是false,因为Col1不是字符串 你犯这个错误的原因是因为你的变量命名方法。根本不知道元素a,b,c,db是什么 由于您的抽象表1,已经很难看到每个变量的含义,因此假设表1是教师表,表2是学生表 如果使用适当的变量名,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"));
结果:如果学生的Col1不是字符串,那么Table2将保持为空,其中(ab=>ab.Table2.Col1.Equals(“ABC”)行不起作用,因为Table2是一个集合。很抱歉,我一开始忘了提到它。其中(ab=>ab.Table2.Col1.Equals(“ABC”))行不起作用,因为Table2是一个集合。很抱歉,我一开始忘了提到它。从外观上看,此查询没有问题。至少您可以使用
==
而不是Equals
。我也尝试了==而不是Equals,但运气不好:-(从外观上看,此查询没有问题。至少您可以使用==
而不是Equals
。我也尝试了==而不是Equals,但没有运气:-(我没有任何关系(主键和外键)在这两个表中。那么我可以在这个场景中使用Include吗?我没有找到任何重载函数,可以在其中使用lambda表达式而不是表名。@John,我已编辑为最简单的解决方案。您可以使用静态值Col1=“ABC”进行联接对于联接来说没有多大意义。如果表1的每个结果都是相同的条件……那么我认为您最好不要将结果放在表1中,并在有意义的地方查询它们,或者查询Col1=“ABC”首先,将同一组值分配给Table1的每个结果,这样就不会对每一行重复查询相同的数据。我没有任何关系(主键和外键)在这两个表中。那么我可以在这个场景中使用Include吗?我没有找到任何重载函数,可以在其中使用lambda表达式而不是表名。@John,我已编辑为最简单的解决方案。您可以使用静态值Col1=“ABC”进行联接对于联接来说没有多大意义。如果表1的每个结果都是相同的条件……那么我认为您最好不要将结果放在表1中,并在有意义的地方查询它们,或者查询Col1=“ABC”首先,将同一组值分配给表1的每个结果,这样就不会对每一行重复查询相同的数据。