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

时间:2018-02-28 14:18:56

标签: c# sql-server entity-framework

我有五张桌子:

Coupons
Coupon_Redemptions
User_Coupon
Wash
Account

SQL Query适用于SQL ServerEntity 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]

1 个答案:

答案 0 :(得分: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,          
    };