Entity Framework: Many-to-Many .Include() not working - entity-framework

I have the following table structure:
That is, a Supplier has a many-to-many relationship with People (of Person).
Supplier 1--* SupplierPerson *--1 Person
A Person has a one-to-many relationship with EmaiLAddresses, TelephoneNumbers and WebResources.
Person 1--* EmailAddress
Person 1--* TelephoneNumber
Person 1--* WebResource
I've highlighted the navigation properties.
Given the LINQ-to-Entities using .Include() to load the dependencies and shape the result-set:
ObjectQuery<Supplier> supplierQuery=((SopEntities)Context).Suppliers
.Include("People")
.Include("People.TelephoneNumbers")
.Include("People.EmailAddresses")
.Include("People.WebResources");
#if TRACE
Trace.WriteLine(string.Format("GetAll(): {0}", supplierQuery.ToTraceString()));
#endif
return supplierQuery;
I get the insanely large and rather useless SQL:
SELECT
[Project5].[ID] AS [ID],
[Project5].[Key] AS [Key],
[Project5].[CompanyName] AS [CompanyName],
[Project5].[AddressLine1] AS [AddressLine1],
[Project5].[AddressLine2] AS [AddressLine2],
[Project5].[TownCity] AS [TownCity],
[Project5].[CountyState] AS [CountyState],
[Project5].[Postcode] AS [Postcode],
[Project5].[Country] AS [Country],
[Project5].[C25] AS [C1],
[Project5].[C2] AS [C2],
[Project5].[C3] AS [C3],
[Project5].[C4] AS [C4],
[Project5].[C5] AS [C5],
[Project5].[C6] AS [C6],
[Project5].[C7] AS [C7],
[Project5].[C8] AS [C8],
[Project5].[C9] AS [C9],
[Project5].[C10] AS [C10],
[Project5].[C11] AS [C11],
[Project5].[C1] AS [C12],
[Project5].[C12] AS [C13],
[Project5].[C13] AS [C14],
[Project5].[C14] AS [C15],
[Project5].[C15] AS [C16],
[Project5].[C16] AS [C17],
[Project5].[C17] AS [C18],
[Project5].[C18] AS [C19],
[Project5].[C19] AS [C20],
[Project5].[C20] AS [C21],
[Project5].[C21] AS [C22],
[Project5].[C22] AS [C23],
[Project5].[C23] AS [C24],
[Project5].[C24] AS [C25]
FROM ( SELECT
[Extent1].[ID] AS [ID],
[Extent1].[Key] AS [Key],
[Extent1].[CompanyName] AS [CompanyName],
[Extent1].[AddressLine1] AS [AddressLine1],
[Extent1].[AddressLine2] AS [AddressLine2],
[Extent1].[TownCity] AS [TownCity],
[Extent1].[CountyState] AS [CountyState],
[Extent1].[Postcode] AS [Postcode],
[Extent1].[Country] AS [Country],
[UnionAll2].[C1] AS [C1],
[UnionAll2].[C2] AS [C2],
[UnionAll2].[C3] AS [C3],
[UnionAll2].[C4] AS [C4],
[UnionAll2].[C5] AS [C5],
[UnionAll2].[C6] AS [C6],
[UnionAll2].[C7] AS [C7],
[UnionAll2].[C8] AS [C8],
[UnionAll2].[C9] AS [C9],
[UnionAll2].[C10] AS [C10],
[UnionAll2].[C11] AS [C11],
[UnionAll2].[C12] AS [C12],
[UnionAll2].[C13] AS [C13],
[UnionAll2].[C14] AS [C14],
[UnionAll2].[C15] AS [C15],
[UnionAll2].[C16] AS [C16],
[UnionAll2].[C17] AS [C17],
[UnionAll2].[C18] AS [C18],
[UnionAll2].[C19] AS [C19],
[UnionAll2].[C20] AS [C20],
[UnionAll2].[C21] AS [C21],
[UnionAll2].[C22] AS [C22],
[UnionAll2].[C23] AS [C23],
[UnionAll2].[C24] AS [C24],
CASE WHEN ([UnionAll2].[C2] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C25]
FROM [dbo].[Supplier] AS [Extent1]
OUTER APPLY (SELECT
[UnionAll1].[C1] AS [C1],
[UnionAll1].[PersonID] AS [C2],
[UnionAll1].[SupplierID] AS [C3],
[UnionAll1].[SupplierID1] AS [C4],
[UnionAll1].[ID] AS [C5],
[UnionAll1].[Title] AS [C6],
[UnionAll1].[FirstName] AS [C7],
[UnionAll1].[Initials] AS [C8],
[UnionAll1].[LastName] AS [C9],
[UnionAll1].[Position] AS [C10],
[UnionAll1].[DepartmentID] AS [C11],
[UnionAll1].[ID1] AS [C12],
[UnionAll1].[Number] AS [C13],
[UnionAll1].[Name] AS [C14],
[UnionAll1].[PersonID1] AS [C15],
[UnionAll1].[TelephoneNumberTypeID] AS [C16],
[UnionAll1].[C2] AS [C17],
[UnionAll1].[C3] AS [C18],
[UnionAll1].[C4] AS [C19],
[UnionAll1].[C5] AS [C20],
[UnionAll1].[C6] AS [C21],
[UnionAll1].[C7] AS [C22],
[UnionAll1].[C8] AS [C23],
[UnionAll1].[C9] AS [C24]
FROM (SELECT
CASE WHEN ([Extent4].[ID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1],
[Extent2].[PersonID] AS [PersonID],
[Extent2].[SupplierID] AS [SupplierID],
[Extent2].[SupplierID] AS [SupplierID1],
[Extent3].[ID] AS [ID],
[Extent3].[Title] AS [Title],
[Extent3].[FirstName] AS [FirstName],
[Extent3].[Initials] AS [Initials],
[Extent3].[LastName] AS [LastName],
[Extent3].[Position] AS [Position],
[Extent3].[DepartmentID] AS [DepartmentID],
[Extent4].[ID] AS [ID1],
[Extent4].[Number] AS [Number],
[Extent4].[Name] AS [Name],
[Extent4].[PersonID] AS [PersonID1],
[Extent4].[TelephoneNumberTypeID] AS [TelephoneNumberTypeID],
CAST(NULL AS int) AS [C2],
CAST(NULL AS varchar(1)) AS [C3],
CAST(NULL AS varchar(1)) AS [C4],
CAST(NULL AS int) AS [C5],
CAST(NULL AS int) AS [C6],
CAST(NULL AS varchar(1)) AS [C7],
CAST(NULL AS varchar(1)) AS [C8],
CAST(NULL AS int) AS [C9]
FROM [dbo].[SupplierPerson] AS [Extent2]
INNER JOIN [dbo].[Person] AS [Extent3] ON [Extent3].[ID] = [Extent2].[PersonID]
LEFT OUTER JOIN [dbo].[TelephoneNumber] AS [Extent4] ON [Extent3].[ID] = [Extent4].[PersonID]
WHERE [Extent1].[ID] = [Extent2].[SupplierID]
UNION ALL
SELECT
2 AS [C1],
[Extent5].[PersonID] AS [PersonID],
[Extent5].[SupplierID] AS [SupplierID],
[Extent5].[SupplierID] AS [SupplierID1],
[Extent6].[ID] AS [ID],
[Extent6].[Title] AS [Title],
[Extent6].[FirstName] AS [FirstName],
[Extent6].[Initials] AS [Initials],
[Extent6].[LastName] AS [LastName],
[Extent6].[Position] AS [Position],
[Extent6].[DepartmentID] AS [DepartmentID],
CAST(NULL AS int) AS [C2],
CAST(NULL AS varchar(1)) AS [C3],
CAST(NULL AS varchar(1)) AS [C4],
CAST(NULL AS int) AS [C5],
CAST(NULL AS int) AS [C6],
[Extent7].[ID] AS [ID1],
[Extent7].[Email] AS [Email],
[Extent7].[Name] AS [Name],
[Extent7].[PersonID] AS [PersonID1],
CAST(NULL AS int) AS [C7],
CAST(NULL AS varchar(1)) AS [C8],
CAST(NULL AS varchar(1)) AS [C9],
CAST(NULL AS int) AS [C10]
FROM [dbo].[SupplierPerson] AS [Extent5]
INNER JOIN [dbo].[Person] AS [Extent6] ON [Extent6].[ID] = [Extent5].[PersonID]
INNER JOIN [dbo].[EmailAddress] AS [Extent7] ON [Extent6].[ID] = [Extent7].[PersonID]
WHERE [Extent1].[ID] = [Extent5].[SupplierID]) AS [UnionAll1]
UNION ALL
SELECT
3 AS [C1],
[Extent8].[PersonID] AS [PersonID],
[Extent8].[SupplierID] AS [SupplierID],
[Extent8].[SupplierID] AS [SupplierID1],
[Extent9].[ID] AS [ID],
[Extent9].[Title] AS [Title],
[Extent9].[FirstName] AS [FirstName],
[Extent9].[Initials] AS [Initials],
[Extent9].[LastName] AS [LastName],
[Extent9].[Position] AS [Position],
[Extent9].[DepartmentID] AS [DepartmentID],
CAST(NULL AS int) AS [C2],
CAST(NULL AS varchar(1)) AS [C3],
CAST(NULL AS varchar(1)) AS [C4],
CAST(NULL AS int) AS [C5],
CAST(NULL AS int) AS [C6],
CAST(NULL AS int) AS [C7],
CAST(NULL AS varchar(1)) AS [C8],
CAST(NULL AS varchar(1)) AS [C9],
CAST(NULL AS int) AS [C10],
[Extent10].[ID] AS [ID1],
[Extent10].[Url] AS [Url],
[Extent10].[Name] AS [Name],
[Extent10].[PersonID] AS [PersonID1]
FROM [dbo].[SupplierPerson] AS [Extent8]
INNER JOIN [dbo].[Person] AS [Extent9] ON [Extent9].[ID] = [Extent8].[PersonID]
INNER JOIN [dbo].[WebResource] AS [Extent10] ON [Extent9].[ID] = [Extent10].[PersonID]
WHERE [Extent1].[ID] = [Extent8].[SupplierID]) AS [UnionAll2]
) AS [Project5]
ORDER BY [Project5].[ID] ASC, [Project5].[C25] ASC, [Project5].[C2] ASC, [Project5].[C3] ASC, [Project5].[C5] ASC, [Project5].[C1] ASC
Which populates the Supplier with People, but not the TelephoneNumbers, EmailAddresses or WebResources.
When executed in SQL Management Studio, I get the incomplete record set:
Clearly, the .Include() is not working due to my misunderstanding of its capabilities.
I really would like to avoid having to call the People schema seperately. How can I have this generate useful SQL?

Related

SQL Server: Left Join and unmatch rows are not coming

I am using left join as a result everything should come from my left table but only matching data coming. I am not able to understand what is wrong in my query or what is missing in it. so please have a look at sample code where anyone can run and reproduce the issue.
create table #tmpModel
(
CSM_ID int,
ID INT,
ParentID INT,
DisplayInCSM Varchar(200),
Type varchar(20),
LineItemID INT
)
create table #tmpLineItem
(
ID INT,
LineItem Varchar(200),
TickerID varchar(20),
)
create table #tmpOutputDetl_CSMTuner
(
Section Varchar(200),
LineItem Varchar(200),
Period Varchar(200),
ItemValue Decimal(18,2),
Ticker varchar(20)
)
INSERT INTO #tmpModel(CSM_ID,ID,ParentID,DisplayInCSM,Type,LineItemID)
VALUES (370,1,0,'Model','SHEET',0)
,(370,2,1,'Segment Details','GROUP',0)
,(370,3,2,'LoyaltyOne','GROUP',0)
,(370,4,3,'Revenue','LINEITEM',198359)
,(370,5,4,'EBITDA','LINEITEM',198360)
,(370,6,5,'Card Services','GROUP',0)
,(370,7,6,'Diluted','LINEITEM',198342)
INSERT INTO #tmpLineItem(ID,LineItem,TickerID)
VALUES (198359,'Net Revenue','ADK')
,(198360,'EBITDA Details','ADK')
,(198342,'Diluted Shares','ADK')
INSERT INTO #tmpOutputDetl_CSMTuner (Section,LineItem,Period,ItemValue,Ticker)
VALUES ('Consensus Model','Net Revenue','2010 FYA',203.22,'ADS')
,('Consensus Model','Net Revenue','2011 FYA',203.22,'ADS')
,('Consensus Model','Net Revenue','2012 FYA',203.22,'ADS')
,('Consensus Model','EBITDA Details','2010 FYA',103.22,'ADS')
,('Consensus Model','EBITDA Details','2011 FYA',109.22,'ADS')
,('Consensus Model','EBITDA Details','2012 FYA',105.22,'ADS')
,('Key Financial','Diluted Shares','2010 FYA',55.22,'ADS')
,('Key Financial','Diluted Shares','2011 FYA',20.22,'ADS')
,('Key Financial','Diluted Shares','2012 FYA',13.22,'ADS')
;with DirectReports as
(
select CSM_ID,
ID,
ParentID,
hierarchy = format(id,'0000'),
level = 0,
DisplayInCSM,
Type,
LineItemID
from #tmpModel
where isnull(ParentID, 0) = 0
union all
select e.CSM_ID,
e.ID,
e.ParentID,
hierarchy = d.hierarchy + '.' + format(e.id,'0000'),
level = level + 1,
e.DisplayInCSM,
e.Type,
e.LineItemID
from #tmpModel e
join DirectReports d on e.ParentID = d.ID
)
/*SELECT * FROM DirectReports Order By hierarchy*/
,Cte1 as
(
SELECT AA.Section,AA.LineItem,AA.Ticker, r.DisplayInCSM, r.Type,r.hierarchy, AA.ItemValue, AA.Period
FROM DirectReports r
LEFT OUTER JOIN
(
Select b.*,L.ID AS LineItemID,L.TickerID
From #tmpOutputDetl_CSMTuner b
INNER JOIN #tmpLineItem L ON b.LineItem= L.LineItem
WHERE L.TickerID='ADK' AND b.Ticker='ADS'
) AA
ON (AA.LineItemID=r.LineItemID)
WHERE AA.Ticker = 'ADS'
)
SELECT * FROM Cte1 ORDER By hierarchy
IF OBJECT_ID(N'tempdb..#tmpModel') IS NOT NULL
BEGIN
DROP TABLE #tmpModel
END
IF OBJECT_ID(N'tempdb..#tmpLineItem') IS NOT NULL
BEGIN
DROP TABLE #tmpLineItem
END
IF OBJECT_ID(N'tempdb..#tmpOutputDetl_CSMTuner') IS NOT NULL
BEGIN
DROP TABLE #tmpOutputDetl_CSMTuner
END
Data should come with Parent child hierarchy wise
Type Group should come but not coming, only Line Item is coming.
Please guide me which area i should rectify to get the desired output.
Solved this way comment this line /WHERE AA.Ticker = 'ADS'/
Now right data is coming.
create table #tmpModel
(
CSM_ID int,
ID INT,
ParentID INT,
DisplayInCSM Varchar(200),
Type varchar(20),
LineItemID INT
)
create table #tmpLineItem
(
ID INT,
LineItem Varchar(200),
TickerID varchar(20),
)
create table #tmpOutputDetl_CSMTuner
(
Section Varchar(200),
LineItem Varchar(200),
Period Varchar(200),
ItemValue Decimal(18,2),
Ticker varchar(20)
)
INSERT INTO #tmpModel(CSM_ID,ID,ParentID,DisplayInCSM,Type,LineItemID)
VALUES (370,1,0,'Model','SHEET',0)
,(370,2,1,'Segment Details','GROUP',0)
,(370,3,2,'LoyaltyOne','GROUP',0)
,(370,4,3,'Revenue','LINEITEM',198359)
,(370,5,4,'EBITDA','LINEITEM',198360)
,(370,6,5,'Card Services','GROUP',0)
,(370,7,6,'Diluted','LINEITEM',198342)
INSERT INTO #tmpLineItem(ID,LineItem,TickerID)
VALUES (198359,'Net Revenue','ADK')
,(198360,'EBITDA Details','ADK')
,(198342,'Diluted Shares','ADK')
INSERT INTO #tmpOutputDetl_CSMTuner (Section,LineItem,Period,ItemValue,Ticker)
VALUES ('Consensus Model','Net Revenue','2010 FYA',203.22,'ADS')
,('Consensus Model','Net Revenue','2011 FYA',203.22,'ADS')
,('Consensus Model','Net Revenue','2012 FYA',203.22,'ADS')
,('Consensus Model','EBITDA Details','2010 FYA',103.22,'ADS')
,('Consensus Model','EBITDA Details','2011 FYA',109.22,'ADS')
,('Consensus Model','EBITDA Details','2012 FYA',105.22,'ADS')
,('Key Financial','Diluted Shares','2010 FYA',55.22,'ADS')
,('Key Financial','Diluted Shares','2011 FYA',20.22,'ADS')
,('Key Financial','Diluted Shares','2012 FYA',13.22,'ADS')
;with DirectReports as
(
select CSM_ID,
ID,
ParentID,
hierarchy = format(id,'0000'),
level = 0,
DisplayInCSM,
Type,
LineItemID
from #tmpModel
where isnull(ParentID, 0) = 0
union all
select e.CSM_ID,
e.ID,
e.ParentID,
hierarchy = d.hierarchy + '.' + format(e.id,'0000'),
level = level + 1,
e.DisplayInCSM,
e.Type,
e.LineItemID
from #tmpModel e
join DirectReports d on e.ParentID = d.ID
)
/*SELECT * FROM DirectReports Order By hierarchy*/
,Cte1 as
(
SELECT AA.Section,AA.LineItem,AA.Ticker, r.DisplayInCSM, r.Type,r.hierarchy, AA.ItemValue, AA.Period
FROM DirectReports r
LEFT OUTER JOIN
(
Select b.*,L.ID AS LineItemID,L.TickerID
From #tmpOutputDetl_CSMTuner b
INNER JOIN #tmpLineItem L ON b.LineItem= L.LineItem
WHERE L.TickerID='ADK' AND b.Ticker='ADS'
) AA
ON (AA.LineItemID=r.LineItemID)
/*WHERE AA.Ticker = 'ADS'*/
)
SELECT * FROM Cte1 WHERE TYPE <> 'SHEET' ORDER By hierarchy
IF OBJECT_ID(N'tempdb..#tmpModel') IS NOT NULL
BEGIN
DROP TABLE #tmpModel
END
IF OBJECT_ID(N'tempdb..#tmpLineItem') IS NOT NULL
BEGIN
DROP TABLE #tmpLineItem
END
IF OBJECT_ID(N'tempdb..#tmpOutputDetl_CSMTuner') IS NOT NULL
BEGIN
DROP TABLE #tmpOutputDetl_CSMTuner
END

Entity framework nested projections are slow

I'm running a query to fetch a users profile. The query get the users details, as well as all the reviews they have posted, as well as the comments in the reviews.
It may well be a case of I'm trying to get back too much, but as the api is getting called from mobile, I'd rather get as much as I can in one network call rather than making multiple network calls.
At the moment this is generating some really long sql, and takes around 25 seconds!
Any tips on how to improve it, or whether projections are even right way to do it
public UserVM GetUserInfo(string userId, string currentUserId)
{
var results =
from u in context.AspNetUsers
where u.Id == userId
select new UserVM
{
Name = u.UserName, Id = u.Id, ProfilePic = u.ProfilePicUrl, FollowerCount = u.Followers.Count, FollowingCount = u.Following.Count,
MemberSince = u.RegisteredDate,
RatingsCount = u.Ratings.Count(x => x.IsDeleted!=true),
FollowedByCurrentUser = currentUserId != null && u.Followers.Any(x => x.FollowedByUserId == currentUserId && x.UserId == userId),
reviews =
from r in u.Ratings
where r.IsDeleted != true
&& r.IsDraft != true
select new RatingVM()
{
ratingId = r.Id,
author_name = r.User.UserName,
userId = r.UserId,
profile_photo_url = r.User.ProfilePicUrl,
rating = r.RatingValue,
text = r.RatingComment,
created = r.Created,
likeCount = r.RatingLikes.Count(x => x.IsLiked && x.RatingId == r.Id),
likedByCurrentUser = currentUserId != null && r.RatingLikes.Any(x => x.IsLiked && x.RatingId == r.Id && x.UserId == currentUserId),
photos = from ri in r.RatingImages
select new PhotoVM { Id = ri.Id, width = 0, height = 0, photo_reference = ri.PhotoUrl, isMember = true, googlePlaceId = r.Place.GooglePlaceId, placeName = r.Place.Name },
comments = from c in r.Comments
where c.IsDeleted != true
select new CommentVM { commentId = c.Id, Created = c.Created, CommentText = c.CommentText, RatingId = r.Id , UserName = c.User.UserName, ProfilePicUrl = c.User.ProfilePicUrl, userId = c.UserId }
}
};
return results.FirstOrDefault();
}
SELECT
[Project17].[C1] AS [C1],
[Project17].[UserName] AS [UserName],
[Project17].[Id] AS [Id],
[Project17].[ProfilePicUrl] AS [ProfilePicUrl],
[Project17].[C32] AS [C2],
[Project17].[C33] AS [C3],
[Project17].[RegisteredDate] AS [RegisteredDate],
[Project17].[C34] AS [C4],
[Project17].[C2] AS [C5],
[Project17].[C31] AS [C6],
[Project17].[C4] AS [C7],
[Project17].[C5] AS [C8],
[Project17].[C6] AS [C9],
[Project17].[C7] AS [C10],
[Project17].[C8] AS [C11],
[Project17].[C9] AS [C12],
[Project17].[C10] AS [C13],
[Project17].[C11] AS [C14],
[Project17].[C12] AS [C15],
[Project17].[C13] AS [C16],
[Project17].[C14] AS [C17],
[Project17].[C3] AS [C18],
[Project17].[C15] AS [C19],
[Project17].[C16] AS [C20],
[Project17].[C17] AS [C21],
[Project17].[C18] AS [C22],
[Project17].[C19] AS [C23],
[Project17].[C20] AS [C24],
[Project17].[C21] AS [C25],
[Project17].[C22] AS [C26],
[Project17].[C23] AS [C27],
[Project17].[C24] AS [C28],
[Project17].[C25] AS [C29],
[Project17].[C26] AS [C30],
[Project17].[C27] AS [C31],
[Project17].[C28] AS [C32],
[Project17].[C29] AS [C33],
[Project17].[C30] AS [C34]
FROM ( SELECT
[Limit1].[Id] AS [Id],
[Limit1].[UserName] AS [UserName],
[Limit1].[ProfilePicUrl] AS [ProfilePicUrl],
[Limit1].[RegisteredDate] AS [RegisteredDate],
[Limit1].[C1] AS [C1],
[Limit1].[C2] AS [C2],
[UnionAll1].[C1] AS [C3],
[UnionAll1].[Id] AS [C4],
[UnionAll1].[Id1] AS [C5],
[UnionAll1].[C2] AS [C6],
[UnionAll1].[C3] AS [C7],
[UnionAll1].[UserId] AS [C8],
[UnionAll1].[C4] AS [C9],
[UnionAll1].[RatingValue] AS [C10],
[UnionAll1].[RatingComment] AS [C11],
[UnionAll1].[Created] AS [C12],
[UnionAll1].[C5] AS [C13],
[UnionAll1].[C6] AS [C14],
[UnionAll1].[Id2] AS [C15],
[UnionAll1].[Id3] AS [C16],
[UnionAll1].[C7] AS [C17],
[UnionAll1].[C8] AS [C18],
[UnionAll1].[PhotoUrl] AS [C19],
[UnionAll1].[C9] AS [C20],
[UnionAll1].[GooglePlaceId] AS [C21],
[UnionAll1].[Name] AS [C22],
[UnionAll1].[C10] AS [C23],
[UnionAll1].[C11] AS [C24],
[UnionAll1].[C12] AS [C25],
[UnionAll1].[C13] AS [C26],
[UnionAll1].[C14] AS [C27],
[UnionAll1].[C15] AS [C28],
[UnionAll1].[C16] AS [C29],
[UnionAll1].[C17] AS [C30],
CASE WHEN ([UnionAll1].[Id] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C31],
[Limit1].[C3] AS [C32],
[Limit1].[C4] AS [C33],
[Limit1].[C5] AS [C34]
FROM (SELECT TOP (1)
#p__linq__4 AS [p__linq__4],
#p__linq__5 AS [p__linq__5],
[Project3].[Id] AS [Id],
[Project3].[UserName] AS [UserName],
[Project3].[ProfilePicUrl] AS [ProfilePicUrl],
[Project3].[RegisteredDate] AS [RegisteredDate],
1 AS [C1],
CASE WHEN ((#p__linq__1 IS NOT NULL) AND ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[Followers] AS [Extent5]
WHERE ([Project3].[Id] = [Extent5].[UserId]) AND ([Extent5].[FollowedByUserId] = #p__linq__2) AND ([Extent5].[UserId] = #p__linq__3)
))) THEN cast(1 as bit) ELSE cast(0 as bit) END AS [C2],
[Project3].[C1] AS [C3],
[Project3].[C2] AS [C4],
[Project3].[C3] AS [C5]
FROM ( SELECT
[Project2].[Id] AS [Id],
[Project2].[UserName] AS [UserName],
[Project2].[ProfilePicUrl] AS [ProfilePicUrl],
[Project2].[RegisteredDate] AS [RegisteredDate],
[Project2].[C1] AS [C1],
[Project2].[C2] AS [C2],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[Ratings] AS [Extent4]
WHERE ([Project2].[Id] = [Extent4].[UserId]) AND (1 <> [Extent4].[IsDeleted])) AS [C3]
FROM ( SELECT
[Project1].[Id] AS [Id],
[Project1].[UserName] AS [UserName],
[Project1].[ProfilePicUrl] AS [ProfilePicUrl],
[Project1].[RegisteredDate] AS [RegisteredDate],
[Project1].[C1] AS [C1],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[Followers] AS [Extent3]
WHERE [Project1].[Id] = [Extent3].[FollowedByUserId]) AS [C2]
FROM ( SELECT
[Extent1].[Id] AS [Id],
[Extent1].[UserName] AS [UserName],
[Extent1].[ProfilePicUrl] AS [ProfilePicUrl],
[Extent1].[RegisteredDate] AS [RegisteredDate],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[Followers] AS [Extent2]
WHERE [Extent1].[Id] = [Extent2].[UserId]) AS [C1]
FROM [dbo].[AspNetUsers] AS [Extent1]
WHERE [Extent1].[Id] = #p__linq__0
) AS [Project1]
) AS [Project2]
) AS [Project3] ) AS [Limit1]
OUTER APPLY (SELECT
CASE WHEN ([Filter10].[Id1] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1],
[Project9].[Id] AS [Id],
[Project9].[Id] AS [Id1],
[Project9].[C1] AS [C2],
[Project9].[C2] AS [C3],
[Project9].[UserId] AS [UserId],
[Project9].[C3] AS [C4],
[Project9].[RatingValue] AS [RatingValue],
[Project9].[RatingComment] AS [RatingComment],
[Project9].[Created] AS [Created],
[Project9].[C5] AS [C5],
[Project9].[C4] AS [C6],
[Filter10].[Id1] AS [Id2],
[Filter10].[Id1] AS [Id3],
CASE WHEN ([Filter10].[Id1] IS NULL) THEN CAST(NULL AS int) ELSE 0 END AS [C7],
CASE WHEN ([Filter10].[Id1] IS NULL) THEN CAST(NULL AS int) ELSE 0 END AS [C8],
[Filter10].[PhotoUrl] AS [PhotoUrl],
CASE WHEN ([Filter10].[Id1] IS NULL) THEN CAST(NULL AS bit) ELSE cast(1 as bit) END AS [C9],
[Filter10].[GooglePlaceId] AS [GooglePlaceId],
[Filter10].[Name] AS [Name],
CAST(NULL AS int) AS [C10],
CAST(NULL AS int) AS [C11],
CAST(NULL AS datetime2) AS [C12],
CAST(NULL AS varchar(1)) AS [C13],
CAST(NULL AS int) AS [C14],
CAST(NULL AS varchar(1)) AS [C15],
CAST(NULL AS varchar(1)) AS [C16],
CAST(NULL AS varchar(1)) AS [C17]
FROM (SELECT
[Project7].[Id] AS [Id],
[Project7].[RatingValue] AS [RatingValue],
[Project7].[RatingComment] AS [RatingComment],
[Project7].[Created] AS [Created],
[Project7].[PlaceId] AS [PlaceId],
[Project7].[UserId] AS [UserId],
[Limit1].[UserName] AS [C1],
N'' AS [C2],
[Limit1].[ProfilePicUrl] AS [C3],
CASE WHEN ((#p__linq__4 IS NOT NULL) AND ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[RatingLikes] AS [Extent8]
WHERE ([Project7].[Id] = [Extent8].[RatingId]) AND ([Extent8].[IsLiked] = 1) AND ([Extent8].[RatingId] = [Project7].[Id]) AND ([Extent8].[UserId] = #p__linq__5)
))) THEN cast(1 as bit) ELSE cast(0 as bit) END AS [C4],
[Project7].[C1] AS [C5]
FROM ( SELECT
[Project6].[Id] AS [Id],
[Project6].[RatingValue] AS [RatingValue],
[Project6].[RatingComment] AS [RatingComment],
[Project6].[Created] AS [Created],
[Project6].[PlaceId] AS [PlaceId],
[Project6].[UserId] AS [UserId],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[RatingLikes] AS [Extent7]
WHERE ([Project6].[Id] = [Extent7].[RatingId]) AND ([Extent7].[IsLiked] = 1) AND ([Extent7].[RatingId] = [Project6].[Id])) AS [C1]
FROM ( SELECT
[Extent6].[Id] AS [Id],
[Extent6].[RatingValue] AS [RatingValue],
[Extent6].[RatingComment] AS [RatingComment],
[Extent6].[Created] AS [Created],
[Extent6].[PlaceId] AS [PlaceId],
[Extent6].[UserId] AS [UserId]
FROM [dbo].[Ratings] AS [Extent6]
WHERE ([Limit1].[Id] = [Extent6].[UserId]) AND (1 <> [Extent6].[IsDeleted]) AND (1 <> [Extent6].[IsDraft])
) AS [Project6]
) AS [Project7] ) AS [Project9]
OUTER APPLY (SELECT [Extent9].[Id] AS [Id1], [Extent9].[PhotoUrl] AS [PhotoUrl], [Project10].[Name] AS [Name], [Project10].[GooglePlaceId] AS [GooglePlaceId]
FROM [dbo].[RatingImages] AS [Extent9]
LEFT OUTER JOIN (SELECT
[Extent10].[Id] AS [Id],
[Extent10].[Name] AS [Name],
[Extent10].[GooglePlaceId] AS [GooglePlaceId]
FROM [dbo].[Places] AS [Extent10]
WHERE [Project9].[PlaceId] = [Extent10].[Id] ) AS [Project10] ON 1 = 1
WHERE [Project9].[Id] = [Extent9].[RatingId] ) AS [Filter10]
UNION ALL
SELECT
2 AS [C1],
[Project15].[Id] AS [Id],
[Project15].[Id] AS [Id1],
[Project15].[C1] AS [C2],
[Project15].[C2] AS [C3],
[Project15].[UserId] AS [UserId],
[Project15].[C3] AS [C4],
[Project15].[RatingValue] AS [RatingValue],
[Project15].[RatingComment] AS [RatingComment],
[Project15].[Created] AS [Created],
[Project15].[C5] AS [C5],
[Project15].[C4] AS [C6],
CAST(NULL AS int) AS [C7],
CAST(NULL AS int) AS [C8],
CAST(NULL AS int) AS [C9],
CAST(NULL AS int) AS [C10],
CAST(NULL AS varchar(1)) AS [C11],
CAST(NULL AS bit) AS [C12],
CAST(NULL AS varchar(1)) AS [C13],
CAST(NULL AS varchar(1)) AS [C14],
[Join2].[Id2] AS [Id2],
[Join2].[Id2] AS [Id3],
[Join2].[Created] AS [Created1],
[Join2].[CommentText] AS [CommentText],
[Project15].[Id] AS [Id4],
[Join2].[UserName] AS [UserName],
[Join2].[ProfilePicUrl] AS [ProfilePicUrl],
[Join2].[UserId] AS [UserId1]
FROM (SELECT
[Project13].[Id] AS [Id],
[Project13].[RatingValue] AS [RatingValue],
[Project13].[RatingComment] AS [RatingComment],
[Project13].[Created] AS [Created],
[Project13].[UserId] AS [UserId],
[Limit1].[UserName] AS [C1],
N'' AS [C2],
[Limit1].[ProfilePicUrl] AS [C3],
CASE WHEN ((#p__linq__4 IS NOT NULL) AND ( EXISTS (SELECT
1 AS [C1]
FROM [dbo].[RatingLikes] AS [Extent13]
WHERE ([Project13].[Id] = [Extent13].[RatingId]) AND ([Extent13].[IsLiked] = 1) AND ([Extent13].[RatingId] = [Project13].[Id]) AND ([Extent13].[UserId] = #p__linq__5)
))) THEN cast(1 as bit) ELSE cast(0 as bit) END AS [C4],
[Project13].[C1] AS [C5]
FROM ( SELECT
[Project12].[Id] AS [Id],
[Project12].[RatingValue] AS [RatingValue],
[Project12].[RatingComment] AS [RatingComment],
[Project12].[Created] AS [Created],
[Project12].[UserId] AS [UserId],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[RatingLikes] AS [Extent12]
WHERE ([Project12].[Id] = [Extent12].[RatingId]) AND ([Extent12].[IsLiked] = 1) AND ([Extent12].[RatingId] = [Project12].[Id])) AS [C1]
FROM ( SELECT
[Extent11].[Id] AS [Id],
[Extent11].[RatingValue] AS [RatingValue],
[Extent11].[RatingComment] AS [RatingComment],
[Extent11].[Created] AS [Created],
[Extent11].[UserId] AS [UserId]
FROM [dbo].[Ratings] AS [Extent11]
WHERE ([Limit1].[Id] = [Extent11].[UserId]) AND (1 <> [Extent11].[IsDeleted]) AND (1 <> [Extent11].[IsDraft])
) AS [Project12]
) AS [Project13] ) AS [Project15]
INNER JOIN (SELECT [Extent14].[Id] AS [Id2], [Extent14].[CommentText] AS [CommentText], [Extent14].[Created] AS [Created], [Extent14].[RatingId] AS [RatingId], [Extent14].[IsDeleted] AS [IsDeleted], [Extent14].[UserId] AS [UserId], [Extent15].[UserName] AS [UserName], [Extent15].[ProfilePicUrl] AS [ProfilePicUrl]
FROM [dbo].[Comments] AS [Extent14]
INNER JOIN [dbo].[AspNetUsers] AS [Extent15] ON [Extent14].[UserId] = [Extent15].[Id] ) AS [Join2] ON ([Project15].[Id] = [Join2].[RatingId]) AND (1 <> [Join2].[IsDeleted])) AS [UnionAll1]
) AS [Project17]
ORDER BY [Project17].[Id] ASC, [Project17].[C31] ASC, [Project17].[C5] ASC, [Project17].[C3] ASC
EF6's loading strategy of using one big SQL query per LINQ query is not optimal for loading complex object graphs. There are several other ways to get your graph loaded.
For instance you could load the root AspNetUser entity, and then traverse the Navigation Properties to build your graph. EF would Lazy Load as needed. And once an entity is cached in the context, subsequent navigations would not cause additional queries.
In fact if you pre-fetch some or all of the related entities, EF will "stitch" or "fix-up" your navigation properties.
So as an optimization, you can write queries that fetch into the context cache the entities that you will need using a few simple and cheap queries.
something like
var user = context.AspNetUsers.Where(u => u.Id == userId).Single();
var followers = context.Followers.Where(f => f.UserId == userId).ToList();
var ratings = context.Ratings.Where(f => f.UserId == userId).ToList();
var ratingIds = ratings.Select(r => r.Id).ToList();
var ratingLikes = context.RatingLikes.Where(x => ratingIds.Contains(x.RatingId) && x.IsLiked ).ToList();
var ratingPhotos = context.RatingPhotos.Where(x => ratingIds.Contains(x.RatingId)).ToList();
Then build your results from the loaded AspNetUser, eg
var u = user;
var results =
select new UserVM
{
Name = u.UserName,
Id = u.Id,
ProfilePic = u.ProfilePicUrl,
FollowerCount = u.Followers.Count, . . .

EF on IDBcommandInterceptor and DBDataReader

I am trying to Mock EF on IDBcommandInterceptor
For insert / update operations it is enough simple - I can return a DbDataReader made of a single field or an int
However, for select operations, if there are some "include", then the shape of the sql result is pretty ... awesome
How could I obtain from
ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> the fields and the names and the corresponding entities for the DbDataReader result?
Thank you,
Example : Trying to read Department(Id, Name) from Id with include on Employee(Id, Name .IDDepartment, DateModification, DateCreation, User)
The Command that obtains the DBDataReader for an include is below .
I want to know the fields names (like C1, ID1, Name1 and others) to be capable of Mocking.
SELECT
[Project2].[Id] AS [Id],
[Project2].[Name] AS [Name],
[Project2].[C1] AS [C1],
[Project2].[Id1] AS [Id1],
[Project2].[Name1] AS [Name1],
[Project2].[IDDepartment] AS [IDDepartment],
[Project2].[DateModification] AS [DateModification],
[Project2].[DateCreation] AS [DateCreation],
[Project2].[User] AS [User],
[Project2].[Archive] AS [Archive]
FROM ( SELECT
[Limit1].[Id] AS [Id],
[Limit1].[Name] AS [Name],
[Extent2].[Id] AS [Id1],
[Extent2].[Name] AS [Name1],
[Extent2].[IDDepartment] AS [IDDepartment],
[Extent2].[DateModification] AS [DateModification],
[Extent2].[DateCreation] AS [DateCreation],
[Extent2].[User] AS [User],
[Extent2].[Archive] AS [Archive],
CASE WHEN ([Extent2].[Id] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
FROM (SELECT TOP (1)
[Extent1].[Id] AS [Id],
[Extent1].[Name] AS [Name]
FROM [dbo].[Department] AS [Extent1]
WHERE [Extent1].[Id] = #p__linq__0 ) AS [Limit1]
LEFT OUTER JOIN [dbo].[Employee] AS [Extent2] ON [Limit1].[Id] = [Extent2].[IDDepartment]
) AS [Project2]
ORDER BY [Project2].[Id] ASC, [Project2].[C1] ASC
You should be able to get the column names from the reader by doing something like this
var columns = Enumerable.Range(0, reader.FieldCount) .Select(reader.GetName).ToList();
That in the case you only need the names. If you get the whole schema for the result table, you could get it by doing this:
DataTable schemaTable = reader.GetSchemaTable();
And then iterate through the collection of rows in the datatable to get the properties of each column.
Does that help to answer your question?

Query on query result

http://sqlfiddle.com/#!3/e4891/1
for the above resulting query(which pivots data) I want to run my one more select condition.
For example
select (C1 & C2) from ‘the above pivoted query results’
IS it possible to do it? CTE will help here?
SQL Server 2008 and above.
Try this:
WITH Data AS
(
select *
from
(
select MemId, Condition_id, condition_result
from t
) x
pivot
(
sum(condition_result)
for condition_id in ([C1], [C2], [C3], [C4])
) p
)
SELECT C1, C2
FROM Data
SQLFiddle: http://sqlfiddle.com/#!3/e4891/3
either change your select to only select the fields that you want:
select [C1], [C2]
from
(
select MemId, Condition_id, condition_result
from t
) x
pivot
(
sum(condition_result)
for condition_id in ([C1], [C2], [C3], [C4])
) p
OR
;with cte
as
(
select *
from
(
select MemId, Condition_id, condition_result
from t
) x
pivot
(
sum(condition_result)
for condition_id in ([C1], [C2], [C3], [C4])
) p
)
select [C1], [C2]
from cte

Telerik's RadGridView + WCF Data Services + Entity Framework = Terrible performance

We have a simple LOB application that:
pulls data from EF
serves data across the wire with WCF Data Services
renders that data on Telerik's RadGridView
This works really well in the default scenario as users are able to filter data by using the built-in Telerik filter control which presents all the options they want.
The problem happens when re-constructing the query sent from WCF Data Services when the 'Contains' operator is used:
WCF Data Services adds a bunch of "IIF" lambda expressions which,
EF then expands into T-SQL CASE statements
This takes a query that should look like:
SELECT TOP (25)
[Project1].[TaskID] AS [TaskID],
[Project1].[ProductSubmissionID] AS [ProductSubmissionID],
...
FROM ( SELECT
[Extent1].[TaskID] AS [TaskID],
[Extent1].[ProductSubmissionID] AS [ProductSubmissionID],
...
FROM [dbo].[Task] AS [Extent1]
LEFT OUTER JOIN [dbo].[OperationDataProduct] AS [Extent2] ON [Extent1].[ProductID] = [Extent2].[ProductID]
LEFT OUTER JOIN [dbo].[vProductOwnership] AS [Extent3] ON [Extent1].[ProductID] = [Extent3].[ProductID]
LEFT OUTER JOIN [dbo].[User] AS [Extent4] ON [Extent2].[ChannelManagerID] = [Extent4].[UserID]
LEFT OUTER JOIN [dbo].[User] AS [Extent5] ON [Extent2].[ProductOwnerID] = [Extent5].[UserID]
WHERE [Extent1].Type IN ('Content','Concept','Financial') AND [Extent1].MarketplaceName LIKE '%prod%'
Into one that looks like this:
SELECT TOP (25)
[Project1].[TaskID] AS [TaskID],
[Project1].[ProductSubmissionID] AS [ProductSubmissionID],
...
FROM ( SELECT
[Extent1].[TaskID] AS [TaskID],
[Extent1].[ProductSubmissionID] AS [ProductSubmissionID],
...
FROM [dbo].[Task] AS [Extent1]
LEFT OUTER JOIN [dbo].[OperationDataProduct] AS [Extent2] ON [Extent1].[ProductID] = [Extent2].[ProductID]
LEFT OUTER JOIN [dbo].[vProductOwnership] AS [Extent3] ON [Extent1].[ProductID] = [Extent3].[ProductID]
LEFT OUTER JOIN [dbo].[User] AS [Extent4] ON [Extent2].[ChannelManagerID] = [Extent4].[UserID]
LEFT OUTER JOIN [dbo].[User] AS [Extent5] ON [Extent2].[ProductOwnerID] = [Extent5].[UserID]
WHERE (CASE WHEN (CASE WHEN (((CASE WHEN (CASE WHEN ([Extent1].[MarketplaceName] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE LOWER([Extent1].[MarketplaceName]) END IS NULL) THEN CAST(NULL AS bit) WHEN (CASE WHEN ([Extent1].[MarketplaceName] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE LOWER([Extent1].[MarketplaceName]) END LIKE N'%prod%') THEN cast(1 as bit) WHEN ( NOT (CASE WHEN ([Extent1].[MarketplaceName] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE LOWER([Extent1].[MarketplaceName]) END LIKE N'%prod%')) THEN cast(0 as bit) END) = 1) AND ([Extent1].[SubmissionOrTaskType] IN (N'Content',N'Concept',N'Financial'))) THEN cast(1 as bit) WHEN ( NOT (((CASE WHEN (CASE WHEN ([Extent1].[MarketplaceName] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE LOWER([Extent1].[MarketplaceName]) END IS NULL) THEN CAST(NULL AS bit) WHEN (CASE WHEN ([Extent1].[MarketplaceName] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE LOWER([Extent1].[MarketplaceName]) END LIKE N'%prod%') THEN cast(1 as bit) WHEN ( NOT (CASE WHEN ([Extent1].[MarketplaceName] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE LOWER([Extent1].[MarketplaceName]) END LIKE N'%prod%')) THEN cast(0 as bit) END) = 1) AND ([Extent1].[SubmissionOrTaskType] IN (N'Content',N'Concept',N'Financial')))) THEN cast(0 as bit) END IS NULL) THEN cast(0 as bit) WHEN (((CASE WHEN (CASE WHEN ([Extent1].[MarketplaceName] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE LOWER([Extent1].[MarketplaceName]) END IS NULL) THEN CAST(NULL AS bit) WHEN (CASE WHEN ([Extent1].[MarketplaceName] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE LOWER([Extent1].[MarketplaceName]) END LIKE N'%prod%') THEN cast(1 as bit) WHEN ( NOT (CASE WHEN ([Extent1].[MarketplaceName] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE LOWER([Extent1].[MarketplaceName]) END LIKE N'%prod%')) THEN cast(0 as bit) END) = 1) AND ([Extent1].[SubmissionOrTaskType] IN (N'Content',N'Concept',N'Financial'))) THEN cast(1 as bit) WHEN ( NOT (((CASE WHEN (CASE WHEN ([Extent1].[MarketplaceName] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE LOWER([Extent1].[MarketplaceName]) END IS NULL) THEN CAST(NULL AS bit) WHEN (CASE WHEN ([Extent1].[MarketplaceName] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE LOWER([Extent1].[MarketplaceName]) END LIKE N'%prod%') THEN cast(1 as bit) WHEN ( NOT (CASE WHEN ([Extent1].[MarketplaceName] IS NULL) THEN CAST(NULL AS varchar(1)) ELSE LOWER([Extent1].[MarketplaceName]) END LIKE N'%prod%')) THEN cast(0 as bit) END) = 1) AND ([Extent1].[SubmissionOrTaskType] IN (N'Content',N'Concept',N'Financial')))) THEN cast(0 as bit) END) = 1
) AS [Project1]
ORDER BY [Project1].[TaskID] ASC
My question is: has anyone bumped into this problem before and is there a low cost solution?
I can see re-writing the EF QueryProvider to be a solution, but it's not exactly low cost.
TIA
We wound up writing a QueryProvider to fix this issue. It wound up being lower cost than originally expected, but still adds quiet a bit of unnecessary complexity. The IQToolkit has some decent examples of how to begin this.