C#LINQ中的左外连接
LINQ查询C#LINQ中的左外连接,c#,entity-framework,linq,entity-framework-6,C#,Entity Framework,Linq,Entity Framework 6,LINQ查询 from rc in context.RC join r in context.R on rc.RId equals r.Id join c in context.C on rc.CId equals c.Id join f in context.F on rc.FId equals f.Id into fg from f in fg.DefaultIfEmpty() join e in context.E on rc.EId equals e.Id into eg from
from rc in context.RC
join r in context.R on rc.RId equals r.Id
join c in context.C on rc.CId equals c.Id
join f in context.F on rc.FId equals f.Id into fg
from f in fg.DefaultIfEmpty()
join e in context.E on rc.EId equals e.Id into eg
from e in eg.DefaultIfEmpty()
生成的SQL是
SELECT *
FROM [dbo].[RC] AS [Extent1]
INNER JOIN [dbo].[R] AS [Extent2] ON [Extent1].[RId] = [Extent2].[Id]
INNER JOIN [dbo].[C] AS [Extent3] ON [Extent1].[CId] = [Extent3].[Id]
INNER JOIN [dbo].[F] AS [Extent4] ON [Extent1].[FId] = [Extent4].[Id]
INNER JOIN [dbo].[E] AS [Extent5] ON [Extent1].[EId] = [Extent5].[Id]
SELECT *
FROM [dbo].[RC] AS [Extent1]
INNER JOIN [dbo].[R] AS [Extent2] ON [Extent1].[RId] = [Extent2].[Id]
INNER JOIN [dbo].[C] AS [Extent3] ON [Extent1].[CId] = [Extent3].[Id]
LEFT JOIN [dbo].[F] AS [Extent4] ON [Extent1].[FId] = [Extent4].[Id]
LEFT JOIN [dbo].[E] AS [Extent5] ON [Extent1].[EId] = [Extent5].[Id]
我想要的是
SELECT *
FROM [dbo].[RC] AS [Extent1]
INNER JOIN [dbo].[R] AS [Extent2] ON [Extent1].[RId] = [Extent2].[Id]
INNER JOIN [dbo].[C] AS [Extent3] ON [Extent1].[CId] = [Extent3].[Id]
INNER JOIN [dbo].[F] AS [Extent4] ON [Extent1].[FId] = [Extent4].[Id]
INNER JOIN [dbo].[E] AS [Extent5] ON [Extent1].[EId] = [Extent5].[Id]
SELECT *
FROM [dbo].[RC] AS [Extent1]
INNER JOIN [dbo].[R] AS [Extent2] ON [Extent1].[RId] = [Extent2].[Id]
INNER JOIN [dbo].[C] AS [Extent3] ON [Extent1].[CId] = [Extent3].[Id]
LEFT JOIN [dbo].[F] AS [Extent4] ON [Extent1].[FId] = [Extent4].[Id]
LEFT JOIN [dbo].[E] AS [Extent5] ON [Extent1].[EId] = [Extent5].[Id]
不确定我在LINQ查询中遗漏了什么
代码的屏幕截图
更新
根据@GertArnold的评论,
RC-F
(表)和RC-E
(表)处于N-1
关联中,其中RC
应持有F
的有效id键引用,但在RC
表中,一些F
id为零,当我进行内部连接时,它将跳过数据
那么,现在我如何强制Entity Framework/LINQ生成左连接
语法,而不根据@GertArnold的注释修改我的DB模式,RC-F(表)和RC-E(表)处于N-1关联中,其中RC应该为F保留有效的id键引用,但在RC表中,一些F id是零,当我进行内部联接时跳过数据
这就是我最终查询结果的原因
List<MyType> myResults;
using (Entities context = new Entities())
{
var results = (from rc in context.RC
join r in context.R on rc.RId equals r.Id
join c in context.C on rc.CId equals c.Id
select rc).ToList();
myResults = results.Select(rc => new MyType
{
Id = rc.Id,
Rule = new IdName
{
Id = rc.R.Id,
Name = rc.R.Name
},
Conjuction = new IdName
{
Id = rc.C.Id,
Name = rc.C.Conjuncation
},
Field = new IdName
{
Id = rc.F!= null ? rc.F.Id : 0,
Name = rc.F!= null ? rc.F.Name : null
},
Expression = new IdName
{
Id = rc.E!= null ? rc.E.Id : 0,
Name = rc.E!= null ? rc.E.Expression : null
},
DisplayOrder = rc.Order,
Value1 = rc.Value,
Value2 = rc.Value2
}).ToList();
}
列出我的结果;
使用(实体上下文=新实体())
{
var results=(来自context.rc中的rc
在rc.RId上的context.r中连接r等于r.Id
在rc.CId上的context.c中连接c等于c.Id
选择rc.ToList();
myResults=results.Select(rc=>newmytype
{
Id=rc.Id,
规则=新的IdName
{
Id=rc.R.Id,
Name=rc.R.Name
},
conconction=新的IdName
{
Id=rc.C.Id,
名称=rc.C.连接
},
字段=新的IdName
{
Id=rc.F!=null?rc.F.Id:0,
Name=rc.F!=null?rc.F.Name:null
},
表达式=新的IdName
{
Id=rc.E!=null?rc.E.Id:0,
Name=rc.E!=null?rc.E.Expression:null
},
DisplayOrder=rc.Order,
Value1=rc.值,
Value2=rc.Value2
}).ToList();
}
根据@GertArnold的评论,RC-F(表)和RC-E(表)处于N-1关联中,其中RC应该为F保留一个有效的id键引用,但在RC表中,一些F id为零,这在我进行内部联接时跳过了数据
这就是我最终查询结果的原因
List<MyType> myResults;
using (Entities context = new Entities())
{
var results = (from rc in context.RC
join r in context.R on rc.RId equals r.Id
join c in context.C on rc.CId equals c.Id
select rc).ToList();
myResults = results.Select(rc => new MyType
{
Id = rc.Id,
Rule = new IdName
{
Id = rc.R.Id,
Name = rc.R.Name
},
Conjuction = new IdName
{
Id = rc.C.Id,
Name = rc.C.Conjuncation
},
Field = new IdName
{
Id = rc.F!= null ? rc.F.Id : 0,
Name = rc.F!= null ? rc.F.Name : null
},
Expression = new IdName
{
Id = rc.E!= null ? rc.E.Id : 0,
Name = rc.E!= null ? rc.E.Expression : null
},
DisplayOrder = rc.Order,
Value1 = rc.Value,
Value2 = rc.Value2
}).ToList();
}
列出我的结果;
使用(实体上下文=新实体())
{
var results=(来自context.rc中的rc
在rc.RId上的context.r中连接r等于r.Id
在rc.CId上的context.c中连接c等于c.Id
选择rc.ToList();
myResults=results.Select(rc=>newmytype
{
Id=rc.Id,
规则=新的IdName
{
Id=rc.R.Id,
Name=rc.R.Name
},
conconction=新的IdName
{
Id=rc.C.Id,
名称=rc.C.连接
},
字段=新的IdName
{
Id=rc.F!=null?rc.F.Id:0,
Name=rc.F!=null?rc.F.Name:null
},
表达式=新的IdName
{
Id=rc.E!=null?rc.E.Id:0,
Name=rc.E!=null?rc.E.Expression:null
},
DisplayOrder=rc.Order,
Value1=rc.值,
Value2=rc.Value2
}).ToList();
}
在lambda语法中,Join
指的是内部连接
,GroupJoin
是左外部连接
这肯定会生成左连接
。您能否显示完整的查询(或可复制的示例)?很可能您有where
子句,它将左连接
转换为内部
我认为RC-F和RC-E是n-1关联,其中需要单侧。EF知道正确的成员不能为null,并且不会生成外部联接。@GertArnold一如既往,直截了当!我认为你是对的,这应该是答案。如果它不是一个显式的where
,那么它应该是一些其他的知识(显然:),如果是这样的话——只有你能证实这一点。但如果是这样,就没有什么可“处理”的了,因为你得到了正确的数据。但也可以用内部联接替换外部联接。更好:用导航属性替换联接。在lambda语法中,Join
指的是内部联接
,GroupJoin
是左侧外部联接
这肯定会生成左侧联接
。您能否显示完整的查询(或可复制的示例)?很可能您有where
子句,它将左连接
转换为内部
我认为RC-F和RC-E是n-1关联,其中需要单侧。EF知道正确的成员不能为null,并且不会生成外部联接。@GertArnold一如既往,直截了当!我认为你是对的,这应该是答案。如果它不是一个显式的where
,那么它应该是一些其他的知识(显然:),如果是这样的话——只有你能证实这一点。但如果是这样,就没有什么可“处理”的了,因为你得到了正确的数据。但也可以用内部联接替换外部联接。更好:用导航属性替换连接。这样你就有了导航属性!还是你加上去的?无论如何,您可以删除第一个ToList
,这样您就可以继续构建e