左连接实体框架,具有1对多关系

问题描述 投票:1回答:1

我有五张桌子:

Coupons
Coupon_Redemptions
User_Coupon
Wash
Account

这是在SQL QuerySQL Server工作的Entity Raw SQL,但是无法让它与LINQ合作,因为1-to-many的关系,懒惰加载无法得到它因为User_coupons,Wash ...是收藏品。

SELECT 
    C.Id AS "CouponId", C.Coupon_code AS "CouponCode", 
    C.Discount_amount AS "DiscountAmount", 
    C.Valid_for_all AS "ValidForAll", C.Expiration_date AS "ExpirationDate", 
    R.Redemption_date AS "RedemptionDate",
    U.Date_added AS "DateAddedToUser", W.Id AS "WashId", A.Name  
FROM 
    Coupon C
    LEFT JOIN User_coupon U on U.CouponId = C.Id
    LEFT JOIN Coupon_redemption R on R.CouponId = C.Id
    LEFT JOIN Wash W on W.CouponId = C.Id
    LEFT JOIN Account A on U.AccountId = A.Id

这是关系图enter image description here的片段

尝试对此查询进行更改,它返回一行。但它看起来很完美。

var results =
                from c in db.Coupons
                from u in c.User_coupon.DefaultIfEmpty()
                from r in c.Coupon_redemption.DefaultIfEmpty()
                from w in c.Washes.DefaultIfEmpty()
                select new {
                    CouponId = c.Id,
                    CouponCode = c.Coupon_code,
                    DiscountAmount = c.Discount_amount,
                    ValidForAll = c.Valid_for_all,
                    ExpirationDate = c.Expiration_date,
                    RedemptionDate = r.Redemption_date,
                    DateAddedToUser = u.Date_added,
                    WashId = w.Id
                };

结果到字符串:

SELECT[Extent1].[Id] AS [Id], [Extent1].[Coupon_code] AS [Coupon_code], [Extent1].[Discount_amount] AS [Discount_amount], [Extent1].[Valid_for_all] AS [Valid_for_all], [Extent1].[Expiration_date] AS [Expiration_date], [Extent3].[Redemption_date] AS [Redemption_date], [Extent2].[Date_added] AS [Date_added], [Extent4].[Id] AS [Id1] 
FROM [dbo].[Coupon] AS [Extent1] 
LEFT OUTER JOIN [dbo].[User_coupon] AS [Extent2] ON [Extent1].[Id] = [Extent2].[CouponId]
LEFT OUTER JOIN [dbo].[Coupon_redemption] AS [Extent3] ON [Extent1].[Id] = [Extent3].[CouponId]
LEFT OUTER JOIN [dbo].[Wash] AS [Extent4] ON [Extent1].[Id] = [Extent4].[CouponId]
c# sql-server entity-framework
1个回答
1
投票

好吧,当包含它们的对象具体化时(即你通过对象实例工作),它们是集合(有或没有延迟加载)。在LINQ to Entities查询中使用时,它们是简单的表导航(连接)。

规则很简单。要获得与集合导航属性的SQL内部联接等效,请使用

from child in parent.Collection

并分别用于左外连接:

from child in parent.Collection.DefaultIfEmpty()

对于引用导航属性,您无法明确指定连接的类型 - 它取决于(受控制)关系是必需还是可选。而不是from,您可以使用let或直接使用导航属性来获取等效的SQL查询连接。

话虽如此,等效的LINQ查询将是这样的:

var query = 
    from c in dbContext.Coupons
    from u in c.User_coupon.DefaultIfEmpty()
    from r in c.Coupon_redemptions.DefaultIfEmpty()
    from w in c.Washes.DefaultIfEmpty()
    let a = u.Account
    select new
    {
        CouponId = c.Id,
        CouponCode = c.Coupon_code,
        DiscountAmount = c.Discount_amount,
        ValidForAll = c.Valid_for_all,
        ExpirationDate = c.Expiration_date, 
        RedemptionDate = r.Redemption_date,
        DateAddedToUser = u.Date_added,
        WashId = w.Id,
        Name = a.Name,          
    };
© www.soinside.com 2019 - 2024. All rights reserved.