Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在LINQ中左连接到实体?_C#_Linq_Entity Framework_Entity Framework 4_Linq To Entities - Fatal编程技术网

C# 在LINQ中左连接到实体?

C# 在LINQ中左连接到实体?,c#,linq,entity-framework,entity-framework-4,linq-to-entities,C#,Linq,Entity Framework,Entity Framework 4,Linq To Entities,我正在尝试LINQ到实体 我有以下问题: 我希望它能做到这一点: SELECT T_Benutzer.BE_User ,T_Benutzer_Benutzergruppen.BEBG_BE FROM T_Benutzer LEFT JOIN T_Benutzer_Benutzergruppen ON T_Benutzer_Benutzergruppen.BEBG_BE = T_Benutzer.BE_ID 最接近我的是: var lol = (

我正在尝试LINQ到实体

我有以下问题: 我希望它能做到这一点:

SELECT 
     T_Benutzer.BE_User
    ,T_Benutzer_Benutzergruppen.BEBG_BE
FROM T_Benutzer

LEFT JOIN T_Benutzer_Benutzergruppen
    ON T_Benutzer_Benutzergruppen.BEBG_BE = T_Benutzer.BE_ID 
最接近我的是:

        var lol = (
            from u in Repo.T_Benutzer

            //where u.BE_ID == 1
            from o in Repo.T_Benutzer_Benutzergruppen.DefaultIfEmpty()
                // on u.BE_ID equals o.BEBG_BE

            where (u.BE_ID == o.BEBG_BE || o.BEBG_BE == null)

            //join bg in Repo.T_Benutzergruppen.DefaultIfEmpty()
            //    on o.BEBG_BG equals bg.ID

            //where bg.ID == 899 

            orderby
                u.BE_Name ascending
                //, bg.Name descending

            //select u 
            select new
            {
                 u.BE_User
                ,o.BEBG_BG
                //, bg.Name 
            }
         ).ToList();
但这将生成与内部联接相同的结果,而不是左联接。
此外,它还创建了一个完全疯狂的SQL:

SELECT 
     [Extent1].[BE_ID] AS [BE_ID]
    ,[Extent1].[BE_User] AS [BE_User]
    ,[Join1].[BEBG_BG] AS [BEBG_BG]
FROM  [dbo].[T_Benutzer] AS [Extent1]

CROSS JOIN  
(
    SELECT 
         [Extent2].[BEBG_BE] AS [BEBG_BE]
        ,[Extent2].[BEBG_BG] AS [BEBG_BG]
    FROM ( SELECT 1 AS X ) AS [SingleRowTable1]
    LEFT OUTER JOIN [dbo].[T_Benutzer_Benutzergruppen] AS [Extent2] 
        ON 1 = 1 
) AS [Join1]

WHERE [Extent1].[BE_ID] = [Join1].[BEBG_BE] 
OR [Join1].[BEBG_BE] IS NULL

ORDER BY [Extent1].[BE_Name] ASC
如何在LINQ-2-entities中以如下方式进行左连接: 另一个人仍然可以理解代码中正在做什么

最好是生成的SQL如下所示:

SELECT 
     T_Benutzer.BE_User
    ,T_Benutzer_Benutzergruppen.BEBG_BE
FROM T_Benutzer

LEFT JOIN T_Benutzer_Benutzergruppen
    ON T_Benutzer_Benutzergruppen.BEBG_BE = T_Benutzer.BE_ID 

你可以阅读我为LINQ中的joins写的一篇文章

以下是使用扩展方法的等效项:

var query = 
Repo.T_Benutzer
.GroupJoin
(
    Repo.T_Benutzer_Benutzergruppen,
    x=>x.BE_ID,
    x=>x.BEBG_BE,
    (o,i)=>new {o,i}
)
.SelectMany
(
    x => x.i.DefaultIfEmpty(),
    (o,i) => new
    {
        BE_User = o.o.BE_User,
        BEBG_BG = (int?)i.BEBG_BG
    }
);
啊,是我自己弄的
LINQ-2-实体的怪癖和夸克。
这看起来很容易理解:

var query2 = (
    from users in Repo.T_Benutzer
    from mappings in Repo.T_Benutzer_Benutzergruppen
        .Where(mapping => mapping.BEBG_BE == users.BE_ID).DefaultIfEmpty()
    from groups in Repo.T_Benutzergruppen
        .Where(gruppe => gruppe.ID == mappings.BEBG_BG).DefaultIfEmpty()
    //where users.BE_Name.Contains(keyword)
    // //|| mappings.BEBG_BE.Equals(666)  
    //|| mappings.BEBG_BE == 666 
    //|| groups.Name.Contains(keyword)

    select new
    {
         UserId = users.BE_ID
        ,UserName = users.BE_User
        ,UserGroupId = mappings.BEBG_BG
        ,GroupName = groups.Name
    }

);


var xy = (query2).ToList();
删除
.DefaultIfEmpty()
,您将获得一个内部联接。

这就是我想要的。

您不仅可以在实体中使用它,还可以在存储过程或其他数据源中使用它:

var customer = (from cus in _billingCommonservice.BillingUnit.CustomerRepository.GetAll()  
                          join man in _billingCommonservice.BillingUnit.FunctionRepository.ManagersCustomerValue()  
                          on cus.CustomerID equals man.CustomerID  
                          // start left join  
                          into a  
                          from b in a.DefaultIfEmpty(new DJBL_uspGetAllManagerCustomer_Result() )  
                          select new { cus.MobileNo1,b.ActiveStatus });  

也许我稍后会来回答,但现在我面临着这个问题。。。如果有帮助,还有一个解决方案(我解决它的方式)


顺便说一句,我试着使用Stefan Steiger代码,这也有帮助,但速度非常慢。

简单的方法是使用Let关键字。这对我有用

from AItem in Db.A
Let BItem = Db.B.Where(x => x.id == AItem.id ).FirstOrDefault() 
Where SomeCondition
Select new YourViewModel
{
    X1 = AItem.a,
    X2 = AItem.b,
    X3 = BItem.c
}

这是一个左连接的模拟。如果B表中的每个项目与某个项目不匹配,BItem return null

Duplicate-@Anand:Nope,join总是产生内部联接,并且从没有条件的情况下是交叉联接,所选的答案是错误的和不充分的,尽管它有许多UPVOUTS,但相关的post-可能重复但投票率最高的答案会生成左外部联接,据林帕德说。(可能自2014年以来情况发生了变化?)你在这里的回答也一样,但更简洁,所以我喜欢。它是T_Benutzer_Benutzergruppen,不是T_Benutzergruppen,但在其他方面是正确的。只是想知道当连接两个以上的表时,这应该如何工作。我在寻找一种更直观易懂的方法。我终于发现了:)就我个人而言,我已经习惯了扩展方法之一,我真的很喜欢它。如果您不断重复
GroupJoin
SelectMany
情侣,您可以有一个不错的解决方案,虽然很长:)您是否有机会在Linq-2-Objects中这样做?因为在那里它会很慢,因为它不使用索引。太好了!第一次看到这样的东西。使用DefaultIfEmpty模拟查询时出错。从这里得到了创建默认类“a.DefaultIfEmpty(new DJBL_uspGetAllManagerUserCustomer_Result())”的想法,并且成功了!不幸的是,创建实体会使集成测试失败,所以这不是一个好的解决方案。这正是我的5表查询所需要的!!!非常感谢你发布这篇文章,它让我省去了几个小时的头疼
    var query2 = (
    from users in Repo.T_Benutzer
    join mappings in Repo.T_Benutzer_Benutzergruppen on mappings.BEBG_BE equals users.BE_ID into tmpMapp
    join groups in Repo.T_Benutzergruppen on groups.ID equals mappings.BEBG_BG into tmpGroups
    from mappings in tmpMapp.DefaultIfEmpty()
    from groups in tmpGroups.DefaultIfEmpty()
    select new
    {
         UserId = users.BE_ID
        ,UserName = users.BE_User
        ,UserGroupId = mappings.BEBG_BG
        ,GroupName = groups.Name
    }

);
from AItem in Db.A
Let BItem = Db.B.Where(x => x.id == AItem.id ).FirstOrDefault() 
Where SomeCondition
Select new YourViewModel
{
    X1 = AItem.a,
    X2 = AItem.b,
    X3 = BItem.c
}