我有五张桌子:
Coupons
Coupon_Redemptions
User_Coupon
Wash
Account
此SQL Query
适用于SQL 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
的摘要
尝试对此查询进行更改,返回一行。但它看起来很完美。
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]
答案 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,
};