I have five tables:
Coupons
Coupon_Redemptions
User_Coupon
Wash
Account
This is SQL Query
that works in SQL Server
and Entity Raw SQL
, but can't get it to work with LINQ
because 1-to-many
releations, with lazy loading can't manage to get it because User_coupons, Wash... are collections.
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
Here is snippet of Relation diagram
Tried variation on this query, it returns one row. But it looks perfect.
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
};
Result to String:
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]
Well, they are collections (with or without lazy loading) when the object containing them is materialized (ie you work through object instance). When used inside LINQ to Entities queries, they are simple table navigations (joins).
The rules are simple. To get the equivalent of SQL inner join for collection navigation property, you use
from child in parent.Collection
and respectively for left outer join:
from child in parent.Collection.DefaultIfEmpty()
For reference navigation property you can't specify explicitly the type of the join - it depends on (is controlled by) whether the relationship is required or optional. And instead of from
, you can use let
or directly the navigation property to get the SQL query join equivalent.
With that being said, the equivalent LINQ query would be something like this:
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,
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.