Inner join the same column of a table to multiple tables - linq

I have a main table Fruit, and I'd like to join it to tables ApplePrice, PearPrice, and BananaPrice.
Fruit
Id Type Date
--------------------
1 Apple 1/1
2 Apple 1/3
3 Banana 1/5
4 Pear 1/7
Common Denominator of [Apple/Pear/Banana]Price (there are many more specific fields for each table):
Date Price F1 F2 ...
-----------------------
1/1 p1
1/2 p2
....
To get the price of each piece of Fruit, I join the Fruit table with each price table separately, then concatenate the results together.
If the Price tables can't be merged into one, do you have a better approach to this problem? For example, construct one Linq query that returns all the information instead of concatenating results from multiple queries.
Appreciate your ideas.

You need to use join into then DefaultIfEmpty. The LINQ equivalent of a SQL LEFT JOIN.
from fruit in fruits
join ap in applePrices
on (fruit.Type + fruit.Date.ToShortDateString()) equals ("Apple" + ap.Date.ToShortDateString())
into aps
from applePrice in aps.DefaultIfEmpty()
This will give:
Fruit | Apple Price | Banana Price | Pear Price
--------+-------------+--------------+------------
Apple | applePrice | null | null
Apple | applePrice | null | null
Banana | null | bananaPrice | null
Pear | null | null | pearPrice
Then select the valid fruitPrice values by the below:
applePrice != null
? applePrice.Price
: bananaPrice != null
? bananaPrice.Price
: pearPrice != null
? pearPrice.Price
: 0 // Default value here if all 3 are null
And use LINQ to select the wanted fields.
The complete result below, I've used an anonymous class to hold my values:
var prices = from fruit in fruits
join ap in applePrices
on (fruit.Type + fruit.Date.ToShortDateString()) equals ("Apple" + ap.Date.ToShortDateString())
into aps
from applePrice in aps.DefaultIfEmpty()
join bp in bananaPrices
on (fruit.Type + fruit.Date.ToShortDateString()) equals ("Banana" + bp.Date.ToShortDateString())
into bps
from bananaPrice in bps.DefaultIfEmpty()
join pp in pearPrices
on (fruit.Type + fruit.Date.ToShortDateString()) equals ("Pear" + pp.Date.ToShortDateString())
into pps
from pearPrice in pps.DefaultIfEmpty()
select new
{
Id = fruit.Id,
Type = fruit.Type,
Date = fruit.Date,
Price =
applePrice != null
? applePrice.Price
: bananaPrice != null
? bananaPrice.Price
: pearPrice != null
? pearPrice.Price
: 0
};

var prices = from T in bank.students
join O in bank.dovres
on (T.code) equals
(O.codestu)
into aps
from applePrice in aps.DefaultIfEmpty()
join Y in bank.rotbes
on (T.code) equals (Y.codestu)
into bps
from bananaPrice in bps.DefaultIfEmpty()
select new
{
Id = T.code,
Type =T.name,
Date = T.family,
father=T.fathername,
T.adi_date, T.faal_date,
// = applePrice.sal + " ماه و " + O.mah + " روز", hk = Y.sal + " ماه و " + Y.mah + " روز"
hj = applePrice != null
? applePrice.sal + " ماه و " + applePrice.mah + " روز"
:"",
hj1 = bananaPrice!= null
? bananaPrice.sal + " ماه و " +bananaPrice.mah + " روز"
: "",
};
dataGridView1.DataSource = prices;
dataGridView1.Columns[0].HeaderText = "کد ";
dataGridView1.Columns[1].HeaderText = "نام";
dataGridView1.Columns[2].HeaderText = "نام خانوادگی";
dataGridView1.Columns[3].HeaderText = "نام پدر";
dataGridView1.Columns[4].HeaderText = " عضویت عادی";
dataGridView1.Columns[5].HeaderText = "عضویت فعال";
dataGridView1.Columns[6].HeaderText = "کسری بسیج";
dataGridView1.Columns[7].HeaderText = "کسری جبهه";
This is the best code for joining 3 or more tables.

Related

How to use Left join linq for multiple tables

I'm Stuck at the joining multiple tables.
Context: i have order table which is linked to productTable(name: ORDER_DETAILS) and recipeTable(ORDER_RECIPEs).I can order product from product menu and recipes from recipe menu. and when i click cart btn, then there must be complete list of product orders and recipe order. what am i getting, both orders are merged in single order but i want these as 2 separate rows under single orders. you can see the result in picture.
var data = (from order in orderEntities.ORDERS
join customer in orderEntities.CUSTOMERS on order.FK_CustomerEmail_Orders equals customer.CustomerEmail
join orderDetail in orderEntities.ORDER_DETAILS on order.OrderId equals orderDetail.FK_OrderId_OrderDetails into s
from orderDetail in s.DefaultIfEmpty()
join product in orderEntities.PRODUCTS on orderDetail.FK_ProductId_OrderDetails equals product.ProductId into p
from product in p.DefaultIfEmpty()
join brand in orderEntities.BRANDS on product.FK_BrandId_Products equals brand.BrandId into b
from brand in b.DefaultIfEmpty()
join orderRecipe in orderEntities.ORDER_RECIPE on order.OrderId equals orderRecipe.FK_OrderId_OrderRecipe into ro
from orderRecipe in ro.DefaultIfEmpty()
join recipe in orderEntities.RECIPEs on orderRecipe.FK_RecipeId_OrderRecipe equals recipe.RecipeId into r
from recipe in r.DefaultIfEmpty()
join rBrand in orderEntities.BRANDS on recipe.FK_BrandId_Recipes equals rBrand.BrandId into rb
from rBrand in rb.DefaultIfEmpty()
//into ps from rev in ps.DefaultIfEmpty()
where customer.CustomerEmail == customerEmail && order.OrderStatus == status &&
brandId == 960
//(brand.BrandId == brandId && rBrand.BrandId == brandId)
orderby order.OrderId descending
Select Query
select new
{
Brand = new
{
BrandId = brand == null ? 0 : brand.BrandId,
BrandName = brand == null ? String.Empty : brand.BrandName,
BrandCategory = brand == null ? String.Empty : brand.BrandCategory
},
Customer = new
{
customer.CustomerId,
customer.CustomerEmail,
customer.CustomerFirstName,
customer.CustomerLastName,
customer.CustomerMobile,
customer.CustomerImageUrl
},
OrderDetail = new
{
OrderDetailId = orderDetail != null ? orderDetail.OrderDetailId : 0 ,
OrderDetailQuantity = orderDetail != null ? orderDetail.OrderDetailQuantity: 0.0 ,
OrderDetailTime = orderDetail != null ? orderDetail.OrderDetailPlaceTime : DateTime.Now,
OrderDetailProductId = orderDetail != null ? orderDetail.FK_ProductId_OrderDetails : 0 ,
OrderDetailOrderId = orderDetail != null ? orderDetail.FK_OrderId_OrderDetails : 0
},
OrderRecipe = new
{
OrderRecipeId = orderRecipe != null ? orderRecipe.OrderRecipeId : 0,
orderRecipeQuantity = orderRecipe != null ? orderRecipe.OrderRecipeQuantity : 0,
OrderRecipePlaceTime = orderRecipe != null ? orderRecipe.OrderRecipePlaceTime : DateTime.Now ,
orderRecipeOrderId = orderRecipe != null ? orderRecipe.FK_OrderId_OrderRecipe: 0,
orderRecipeRecipeId = orderRecipe != null ? orderRecipe.FK_RecipeId_OrderRecipe :0
},
Product = new
{
ProductId = product == null ? 0 : product.ProductId,
ProductTitle = product == null ? String.Empty : product.ProductTitle,
ProductOldPrice = product == null ? 0.0 : product.ProductOldPrice,
ProductNewPrice = product == null ? 0.0 : product.ProductNewPrice,
ProductImageUrl = product == null ? String.Empty : product.ProductImageUrl,
ProductContent = product == null ? String.Empty : product.ProductContent,
ProductCategory = product == null ? String.Empty : product.ProductCategory,
ProductSubCategory = product == null ? String.Empty : product.ProductSubCategory,
ProductPostedTime = product == null ? DateTime.Now : product.ProductPostedTime,
ProductStocks = product == null ? String.Empty : product.ProductStocks,
ProductStatus = product == null ? String.Empty : product.ProductStatus,
ProductBrandId = product == null ? 0 : product.FK_BrandId_Products
},
Recipe = new
{
RecipeId = recipe != null ? recipe.RecipeId: 0 ,
RecipeTitle = recipe != null ? recipe.RecipeTitle : String.Empty,
RecipePrice = recipe != null ? recipe.RecipePrice : 0,
RecipeImage = recipe != null ? recipe.RecipeImage: String.Empty,
RecipeCategory = recipe != null ? recipe.RecipeCategory: String.Empty,
RecipePostTime = recipe != null ? recipe.RecipePostTime : DateTime.Now,
RecipeStock = recipe != null ? recipe.RecipeStock: String.Empty,
RecipeStatus = recipe != null ? recipe.RecipeStatus : false,
ProductBrandId = recipe != null ? recipe.FK_BrandId_Recipes: 0
},
order.OrderId,
order.OrderPlaceTime,
order.OrderCompletedTime,
order.OrderStatus,
order.FK_CustomerEmail_Orders
}).Skip(offset).Take(limit).ToList();
I have followed this :
Left Join Linq
you can see here, Products and recipe are combined in same order but if product is there, recipe should be 0 and vice versa. like this:
order:{
brand:{ 10 },OrderRecipe:{ 1 },Recipe{1}, orderDetail:{ 0 },products: {0} orderId: 1 ..},{
brand:{ 10 },OrderRecipe:{ 2 },Recipe{2}, orderDetail:{ 0 },products: {0} orderId: 1 ..},{
brand:{ 10 },orderDetail:{ 1 },products: {1},OrderRecipe:{ 0},Recipe{0} orderId: 1...},{
brand:{ 10 },orderDetail:{ 2 },products: {2},OrderRecipe:{ 0},Recipe{0} orderId: 1...}
If there's any other better way to do this. kindly correct me here.
You will surely get the result like that, because you have joined both tables with your ORDER.
What you can do is:
1) you can make the objects separately like this:
var recipe = (from db.order ...
join orderRecipe in orderEntities.ORDER_RECIPE on order.OrderId equals orderRecipe.FK_OrderId_OrderRecipe into ro
from orderRecipe in ro.DefaultIfEmpty()
join recipe in orderEntities.RECIPEs on orderRecipe.FK_RecipeId_OrderRecipe equals recipe.RecipeId into r
from recipe in r.DefaultIfEmpty()
join rBrand in orderEntities.BRANDS on recipe.FK_BrandId_Recipes equals rBrand.BrandId into rb
from rBrand in rb.DefaultIfEmpty())
and after that you can use both the objects accordingly
2) if you want to use join on both in same query. check your generated sql against linq in visual studio. what you gonna do is use right join for your products and left for your recipes..
i hope this will help you.

DAX in calculated column

I have two tables as below.
Table1
CaseId
66787
Table2
PrimaryKey CaseId SeqNo Status Primary Code CodeCareNo
85248 66787 6 Active N 876 8775568
70728 66787 1 Inactive N 876 3661794
79008 66787 5 Active Y 876 3766066
86868 66787 7 Active Y 876 3287735
Table 1 has one to many relationships with Table2 and the relating column in CaseId.
I have a requirement to create a calculated column in Table1 in my model project. The calculated column should display a text like (Code) CodeCareNo (eg: (876) 3766066) for each CaseId in Table1 with the values from Code and CodeCareNo columns of Table2 which has Primary = “Y” and Status = “Active” with Seq No as the minimum value among the primary active code numbers for the CaseId. Also if the Code or CodeCareNo is null the calculated column should show blank value. I am able to get the desired result with below query but I feel it bit messy. Can someone help me in simplifying the same?
=IF("(" & LOOKUPVALUE(Table2[Code], Table2[CaseId], Table1[CaseId],
Table2[Primary], "Y", Table2[Status], "Active", Table2[SeqNo],
MINX(FILTER(Table2, ( Table2[Primary] = "Y" && Table2[Status] = "Active" &&
Table2[CaseId] = Table1[CaseId])), Table2[SeqNo])) & ") " &
LOOKUPVALUE(Table2[CodeCareNo], Table2[CaseId], Table1[CaseId],
Table2[Primary], "Y", Table2[Status], "Active", Table2[SeqNo],
MINX(FILTER(Table2, ( Table2[Primary] = "Y" && Table2[Status] = "Active" &&
Table2[CaseId] = Table1[CaseId])), Table2[SeqNo])) = "() ", BLANK(), "(" &
LOOKUPVALUE(Table2[Code], Table2[CaseId], Table1[CaseId], Table2[Primary],
"Y", Table2[Status], "Active", Table2[SeqNo], MINX(FILTER(Table2, (
Table2[Primary] = "Y" && Table2[Status] = "Active" && Table2[CaseId] =
Table1[CaseId])), Table2[SeqNo])) & ") " & LOOKUPVALUE(Table2[CodeCareNo],
Table2[CaseId], Table1[CaseId], Table2[Primary], "Y", Table2[Status],
"Active", Table2[SeqNo], MINX(FILTER(Table2, ( Table2[Primary] = "Y" &&
Table2[Status] = "Active" && Table2[CaseId] = Table1[CaseId])),
Table2[SeqNo])) )
That's quite the mess. Try this formulation:
CodeCase =
VAR SeqNo = CALCULATE(MIN(Table2[SeqNo]), Table2[Primary] = "Y", Table2[Status] = "Active")
VAR Code = LOOKUPVALUE(Table2[Code], Table2[SeqNo], SeqNo)
VAR CodeCareNo = LOOKUPVALUE(Table2[CodeCareNo], Table2[SeqNo], SeqNo)
RETURN IF(ISBLANK(Code) || ISBLANK(CodeCareNo), BLANK(), "(" & Code & ") " & CodeCareNo)
(I like to use variables for computational efficiency and readability.)

Alias Column In Resultset

I have a query in backend spring project, where I create a field alias named agent_id but I don´t have that column in Model. What is the best approach for showing this as a field in table view in front end???.
Here´s the query:
Query query = em.createNativeQuery("SELECT" +
" ips.*, " +
" s.mls_id AS imported," +
" p.INTEGRATOR_SALES_ASSOCIATED_ID AS agent_id " +
"FROM test1.ilist_property_summary ips " +
" LEFT JOIN test1.statistics s ON s.mls_id = ips.INTEGRATOR_PROPERTY_ID " +
" LEFT JOIN test1.person p ON p.INTEGRATOR_SALES_ASSOCIATED_ID = ips.INTEGRATOR_SALES_ASSOCIATED_ID " +
"WHERE ips.AGENCY_ID = :agencyId AND (s.statistics_type = 1 OR s.statistics_type IS NULL) AND ips.ORIG_LISTING_DATE BETWEEN :startDate AND :endDate");
query.setParameter("agencyId", agencyId)
.setParameter("startDate", DateUtil.asDate(startDate), TemporalType.DATE)
.setParameter("endDate", DateUtil.asDate(endDate), TemporalType.DATE);
return (List<PropertyVO>) query.getResultList().stream().map(o -> processProperty((Object[]) o)).collect(Collectors.<PropertyVO>toList());
I already have a field that shows agent_id, but not fetched with same field of table Person. I need to retrieve that field agent id alias fetched from left join.
I followed another approach:
Query query = em.createNativeQuery("SELECT" +
" ips.id, ips.agency_id, ips.integrator_property_id, ips.orig_listing_date, ips.contract_type," +
" ips.transaction_type, ips.current_listing_price, ips.current_listing_currency, ips.apartment_number, ips.commercial_residential," +
" ips.commission_percent, ips.commission_value, ips.property_type, ips.street_name, ips.street_number," +
" s.mls_id AS imported," +
" p.INTEGRATOR_SALES_ASSOCIATED_ID AS INTEGRATOR_SALES_ASSOCIATED_ID" +
" FROM test1.ilist_property_summary ips " +
" LEFT JOIN test1.statistics s ON s.mls_id = ips.INTEGRATOR_PROPERTY_ID " +
" LEFT JOIN test1.person p ON p.INTEGRATOR_SALES_ASSOCIATED_ID = ips.INTEGRATOR_SALES_ASSOCIATED_ID " +
"WHERE ips.AGENCY_ID = :agencyId AND (s.statistics_type = 1 OR s.statistics_type IS NULL) AND ips.ORIG_LISTING_DATE BETWEEN :startDate AND :endDate ");
Here field
INTEGRATOR_SALES_ASSOCIATED_ID
is taken from table p, and not from ips. I just selected specific fields so this one could be taken from the other table.

NullReferenceException Error when trying to iterate a IEnumerator

I have a datatable and want to select some records with LinQ in this format:
var result2 = from row in dt.AsEnumerable()
where row.Field<string>("Media").Equals(MediaTp, StringComparison.CurrentCultureIgnoreCase)
&& (String.Compare(row.Field<string>("StrDate"), dtStart.Year.ToString() +
(dtStart.Month < 10 ? '0' + dtStart.Month.ToString() : dtStart.Month.ToString()) +
(dtStart.Day < 10 ? '0' + dtStart.Day.ToString() : dtStart.Day.ToString())) >= 0
&& String.Compare(row.Field<string>("StrDate"), dtEnd.Year.ToString() +
(dtEnd.Month < 10 ? '0' + dtEnd.Month.ToString() : dtEnd.Month.ToString()) +
(dtEnd.Day < 10 ? '0' + dtEnd.Day.ToString() : dtEnd.Day.ToString())) <= 0)
group row by new { Year = row.Field<int>("Year"), Month = row.Field<int>("Month"), Day = row.Field<int>("Day") } into grp
orderby grp.Key.Year, grp.Key.Month, grp.Key.Day
select new
{
CurrentDate = grp.Key.Year + "/" + grp.Key.Month + "/" + grp.Key.Day,
DayOffset = (new DateTime(grp.Key.Year, grp.Key.Month, grp.Key.Day)).Subtract(dtStart).Days,
Count = grp.Sum(r => r.Field<int>("Count"))
};
and in this code, I try to iterate it with the following code:
foreach (var row in result2)
{
//... row.DayOffset.ToString() + ....
}
this issue occurred :
Object reference not set to an instance of an object.
I think it happens when there's no record with above criteria.
I tried to change it to enumerator like this , and use MoveNext() to check the data is on that or not:
result2.GetEnumerator();
if (enumerator2.MoveNext()) {//--}
but still the same error.
whats the problem?
I guess in one or more rows Media is null.
You then call Equals on null, which results in a NullReferenceException.
You could add a null check:
var result2 = from row in dt.AsEnumerable()
where row.Field<string>("Media") != null
&& row.Field<string>("Media").Equals(MediaTp, StringComparison.CurrentCultureIgnoreCase)
...
or use a surrogate value like:
var result2 = from row in dt.AsEnumerable()
let media = row.Field<string>("Media") ?? String.Empty
where media.Equals(MediaTp, StringComparison.CurrentCultureIgnoreCase)
...
(note that the last approach is slightly different)

Linq To Entities Generating Big Queries

I've been running a trace on some of the queries Linq is generating and they seem very unoptimized and clumsy.
I realise you dont know my data structure but is tere anything immidiatly wrong with the following linq query
IQueryable<Tasks> tl = db.Tasks
.Include("Catagories")
.Include("Projects")
.Include("TaskStatuses")
.Include("AssignedTo")
.Where
(t => (t.TaskStatuses.TaskStatusId.Equals(currentStatus) | currentStatus == -1) &
(t.Projects.ProjectId.Equals(projectId) | projectId == -1) &
(t.Subject.Contains(SearchText) | t.Description.Contains(SearchText) | SearchText == "" | SearchText == null) &
(t.Projects.Active == true) &
(t.Catagories.Active == true || t.Catagories==null) &
(t.LoggedBy.UserProfile.Companies.CompanyId == CompanyId) &
(assignedToGuid == rnd | t.AssignedTo.UserId.Equals(assignedToGuid))).OrderBy(SortField + " " + SortOrder);
When it runs it generates this SQL query
exec sp_executesql N'SELECT
[Project1].[C1] AS [C1],
[Project1].[TaskId] AS [TaskId],
[Project1].[Subject] AS [Subject],
[Project1].[Description] AS [Description],
[Project1].[EstimateDays] AS [EstimateDays],
[Project1].[EstimateHours] AS [EstimateHours],
[Project1].[DateLogged] AS [DateLogged],
[Project1].[DateModified] AS [DateModified],
[Project1].[AssignedTo] AS [AssignedTo],
[Project1].[C2] AS [C2],
[Project1].[CatagoryId] AS [CatagoryId],
[Project1].[CatagoryName] AS [CatagoryName],
[Project1].[CreatedOn] AS [CreatedOn],
[Project1].[Active] AS [Active],
[Project1].[CreatedBy] AS [CreatedBy],
[Project1].[C3] AS [C3],
[Project1].[ProjectId] AS [ProjectId],
[Project1].[ProjectName] AS [ProjectName],
[Project1].[CreatedOn1] AS [CreatedOn1],
[Project1].[Active1] AS [Active1],
[Project1].[CreatedBy1] AS [CreatedBy1],
[Project1].[TaskStatusId] AS [TaskStatusId],
[Project1].[StatusName] AS [StatusName],
[Project1].[C4] AS [C4],
[Project1].[ApplicationId] AS [ApplicationId],
[Project1].[UserId] AS [UserId],
[Project1].[UserName] AS [UserName],
[Project1].[LoweredUserName] AS [LoweredUserName],
[Project1].[MobileAlias] AS [MobileAlias],
[Project1].[IsAnonymous] AS [IsAnonymous],
[Project1].[LastActivityDate] AS [LastActivityDate],
[Project1].[UserId1] AS [UserId1],
[Project1].[UserId2] AS [UserId2]
FROM ( SELECT
[Filter1].[TaskId] AS [TaskId],
[Filter1].[Subject] AS [Subject],
[Filter1].[Description] AS [Description],
[Filter1].[AssignedTo] AS [AssignedTo],
[Filter1].[EstimateDays] AS [EstimateDays],
[Filter1].[EstimateHours] AS [EstimateHours],
[Filter1].[DateLogged] AS [DateLogged],
[Filter1].[DateModified] AS [DateModified],
[Filter1].[CatagoryId1] AS [CatagoryId],
[Filter1].[CatagoryName] AS [CatagoryName],
[Filter1].[CreatedBy1] AS [CreatedBy],
[Filter1].[CreatedOn1] AS [CreatedOn],
[Filter1].[Active1] AS [Active],
[Filter1].[ProjectId1] AS [ProjectId],
[Filter1].[ProjectName1] AS [ProjectName],
[Filter1].[CreatedOn2] AS [CreatedOn1],
[Filter1].[Active2] AS [Active1],
[Filter1].[CreatedBy2] AS [CreatedBy1],
[Filter1].[TaskStatusId1] AS [TaskStatusId],
[Filter1].[StatusName] AS [StatusName],
[Filter1].[ApplicationId1] AS [ApplicationId],
[Filter1].[UserId1] AS [UserId],
[Filter1].[UserName1] AS [UserName],
[Filter1].[LoweredUserName1] AS [LoweredUserName],
[Filter1].[MobileAlias1] AS [MobileAlias],
[Filter1].[IsAnonymous1] AS [IsAnonymous],
[Filter1].[LastActivityDate1] AS [LastActivityDate],
[Filter1].[UserId2] AS [UserId1],
[Join12].[UserId3] AS [UserId2],
1 AS [C1],
1 AS [C2],
1 AS [C3],
1 AS [C4]
FROM (SELECT [Extent1].[TaskId] AS [TaskId], [Extent1].[Subject] AS [Subject], [Extent1].[Description] AS [Description], [Extent1].[ProjectId] AS [ProjectId2], [Extent1].[TaskStatusId] AS [TaskStatusId2], [Extent1].[LoggedBy] AS [LoggedBy], [Extent1].[AssignedTo] AS [AssignedTo], [Extent1].[EstimateDays] AS [EstimateDays], [Extent1].[EstimateHours] AS [EstimateHours], [Extent1].[DateLogged] AS [DateLogged], [Extent1].[DateModified] AS [DateModified], [Extent1].[CatagoryId] AS [CatagoryId2], [Extent2].[ProjectId] AS [ProjectId3], [Extent2].[ProjectName] AS [ProjectName2], [Extent2].[CreatedOn] AS [CreatedOn3], [Extent2].[CreatedBy] AS [CreatedBy3], [Extent2].[Active] AS [Active3], [Extent3].[CatagoryId] AS [CatagoryId1], [Extent3].[CatagoryName] AS [CatagoryName], [Extent3].[CreatedBy] AS [CreatedBy1], [Extent3].[CreatedOn] AS [CreatedOn1], [Extent3].[Active] AS [Active1], [Join3].[ApplicationId2], [Join3].[UserId4], [Join3].[UserName2], [Join3].[LoweredUserName2], [Join3].[MobileAlias2], [Join3].[IsAnonymous2], [Join3].[LastActivityDate2], [Join3].[UserId5], [Join3].[CompanyId1], [Join3].[Forename1], [Join3].[Surname1], [Join3].[Active4], [Extent6].[UserId] AS [UserId6], [Extent6].[CompanyId] AS [CompanyId2], [Extent6].[Forename] AS [Forename2], [Extent6].[Surname] AS [Surname2], [Extent6].[Active] AS [Active5], [Extent7].[ProjectId] AS [ProjectId1], [Extent7].[ProjectName] AS [ProjectName1], [Extent7].[CreatedOn] AS [CreatedOn2], [Extent7].[CreatedBy] AS [CreatedBy4], [Extent7].[Active] AS [Active2], [Extent8].[ProjectId] AS [ProjectId4], [Extent8].[ProjectName] AS [ProjectName3], [Extent8].[CreatedOn] AS [CreatedOn4], [Extent8].[CreatedBy] AS [CreatedBy2], [Extent8].[Active] AS [Active6], [Extent9].[TaskStatusId] AS [TaskStatusId1], [Extent9].[StatusName] AS [StatusName], [Extent10].[ApplicationId] AS [ApplicationId1], [Extent10].[UserId] AS [UserId1], [Extent10].[UserName] AS [UserName1], [Extent10].[LoweredUserName] AS [LoweredUserName1], [Extent10].[MobileAlias] AS [MobileAlias1], [Extent10].[IsAnonymous] AS [IsAnonymous1], [Extent10].[LastActivityDate] AS [LastActivityDate1], [Join10].[ApplicationId3], [Join10].[UserId7], [Join10].[UserName3], [Join10].[LoweredUserName3], [Join10].[MobileAlias3], [Join10].[IsAnonymous3], [Join10].[LastActivityDate3], [Join10].[ApplicationId4], [Join10].[UserId2], [Join10].[Password], [Join10].[PasswordFormat], [Join10].[PasswordSalt], [Join10].[MobilePIN], [Join10].[Email], [Join10].[LoweredEmail], [Join10].[PasswordQuestion], [Join10].[PasswordAnswer], [Join10].[IsApproved], [Join10].[IsLockedOut], [Join10].[CreateDate], [Join10].[LastLoginDate], [Join10].[LastPasswordChangedDate], [Join10].[LastLockoutDate], [Join10].[FailedPasswordAttemptCount], [Join10].[FailedPasswordAttemptWindowStart], [Join10].[FailedPasswordAnswerAttemptCount], [Join10].[FailedPasswordAnswerAttemptWindowStart], [Join10].[Comment]
FROM [dbo].[Tasks] AS [Extent1]
INNER JOIN [dbo].[Projects] AS [Extent2] ON [Extent1].[ProjectId] = [Extent2].[ProjectId]
LEFT OUTER JOIN [dbo].[Catagories] AS [Extent3] ON [Extent1].[CatagoryId] = [Extent3].[CatagoryId]
LEFT OUTER JOIN (SELECT [Extent4].[ApplicationId] AS [ApplicationId2], [Extent4].[UserId] AS [UserId4], [Extent4].[UserName] AS [UserName2], [Extent4].[LoweredUserName] AS [LoweredUserName2], [Extent4].[MobileAlias] AS [MobileAlias2], [Extent4].[IsAnonymous] AS [IsAnonymous2], [Extent4].[LastActivityDate] AS [LastActivityDate2], [Extent5].[UserId] AS [UserId5], [Extent5].[CompanyId] AS [CompanyId1], [Extent5].[Forename] AS [Forename1], [Extent5].[Surname] AS [Surname1], [Extent5].[Active] AS [Active4]
FROM [dbo].[aspnet_Users] AS [Extent4]
LEFT OUTER JOIN [dbo].[UserProfile] AS [Extent5] ON [Extent4].[UserId] = [Extent5].[UserId] ) AS [Join3] ON [Extent1].[AssignedTo] = [Join3].[UserId4]
INNER JOIN [dbo].[UserProfile] AS [Extent6] ON [Join3].[UserId5] = [Extent6].[UserId]
LEFT OUTER JOIN [dbo].[Projects] AS [Extent7] ON [Extent1].[ProjectId] = [Extent7].[ProjectId]
LEFT OUTER JOIN [dbo].[Projects] AS [Extent8] ON [Extent1].[ProjectId] = [Extent8].[ProjectId]
LEFT OUTER JOIN [dbo].[TaskStatuses] AS [Extent9] ON [Extent1].[TaskStatusId] = [Extent9].[TaskStatusId]
LEFT OUTER JOIN [dbo].[aspnet_Users] AS [Extent10] ON [Extent1].[LoggedBy] = [Extent10].[UserId]
LEFT OUTER JOIN (SELECT [Extent11].[ApplicationId] AS [ApplicationId3], [Extent11].[UserId] AS [UserId7], [Extent11].[UserName] AS [UserName3], [Extent11].[LoweredUserName] AS [LoweredUserName3], [Extent11].[MobileAlias] AS [MobileAlias3], [Extent11].[IsAnonymous] AS [IsAnonymous3], [Extent11].[LastActivityDate] AS [LastActivityDate3], [Extent12].[ApplicationId] AS [ApplicationId4], [Extent12].[UserId] AS [UserId2], [Extent12].[Password] AS [Password], [Extent12].[PasswordFormat] AS [PasswordFormat], [Extent12].[PasswordSalt] AS [PasswordSalt], [Extent12].[MobilePIN] AS [MobilePIN], [Extent12].[Email] AS [Email], [Extent12].[LoweredEmail] AS [LoweredEmail], [Extent12].[PasswordQuestion] AS [PasswordQuestion], [Extent12].[PasswordAnswer] AS [PasswordAnswer], [Extent12].[IsApproved] AS [IsApproved], [Extent12].[IsLockedOut] AS [IsLockedOut], [Extent12].[CreateDate] AS [CreateDate], [Extent12].[LastLoginDate] AS [LastLoginDate], [Extent12].[LastPasswordChangedDate] AS [LastPasswordChangedDate], [Extent12].[LastLockoutDate] AS [LastLockoutDate], [Extent12].[FailedPasswordAttemptCount] AS [FailedPasswordAttemptCount], [Extent12].[FailedPasswordAttemptWindowStart] AS [FailedPasswordAttemptWindowStart], [Extent12].[FailedPasswordAnswerAttemptCount] AS [FailedPasswordAnswerAttemptCount], [Extent12].[FailedPasswordAnswerAttemptWindowStart] AS [FailedPasswordAnswerAttemptWindowStart], [Extent12].[Comment] AS [Comment]
FROM [dbo].[aspnet_Users] AS [Extent11]
LEFT OUTER JOIN [dbo].[aspnet_Membership] AS [Extent12] ON [Extent11].[UserId] = [Extent12].[UserId] ) AS [Join10] ON [Extent1].[LoggedBy] = [Join10].[UserId7]
WHERE (1 = [Extent2].[Active]) AND ((1 = [Extent3].[Active]) OR ([Extent3].[CatagoryId] IS NULL)) ) AS [Filter1]
LEFT OUTER JOIN (SELECT [Extent13].[ApplicationId] AS [ApplicationId], [Extent13].[UserId] AS [UserId8], [Extent13].[UserName] AS [UserName], [Extent13].[LoweredUserName] AS [LoweredUserName], [Extent13].[MobileAlias] AS [MobileAlias], [Extent13].[IsAnonymous] AS [IsAnonymous], [Extent13].[LastActivityDate] AS [LastActivityDate], [Extent14].[UserId] AS [UserId3], [Extent14].[CompanyId] AS [CompanyId], [Extent14].[Forename] AS [Forename], [Extent14].[Surname] AS [Surname], [Extent14].[Active] AS [Active]
FROM [dbo].[aspnet_Users] AS [Extent13]
LEFT OUTER JOIN [dbo].[UserProfile] AS [Extent14] ON [Extent13].[UserId] = [Extent14].[UserId] ) AS [Join12] ON [Filter1].[LoggedBy] = [Join12].[UserId8]
WHERE (([Filter1].[TaskStatusId2] = #p__linq__49) OR (-1 = #p__linq__50)) AND (([Filter1].[ProjectId2] = #p__linq__51) OR (-1 = #p__linq__52)) AND (((CAST(CHARINDEX(#p__linq__53, [Filter1].[Subject]) AS int)) > 0) OR ((CAST(CHARINDEX(#p__linq__54, [Filter1].[Description]) AS int)) > 0) OR (N'''' = #p__linq__55) OR (#p__linq__56 IS NULL)) AND ([Filter1].[CompanyId2] = #p__linq__57) AND ((#p__linq__58 = #p__linq__59) OR ([Filter1].[LoggedBy] = #p__linq__60))
) AS [Project1]
ORDER BY [Project1].[TaskId] ASC',N'#p__linq__49 int,#p__linq__50 int,#p__linq__51 int,#p__linq__52 int,#p__linq__53 nvarchar(4000),#p__linq__54 nvarchar(4000),#p__linq__55 nvarchar(4000),#p__linq__56 nvarchar(4000),#p__linq__57 int,#p__linq__58 uniqueidentifier,#p__linq__59 uniqueidentifier,#p__linq__60 uniqueidentifier',#p__linq__49=1,#p__linq__50=1,#p__linq__51=2,#p__linq__52=2,#p__linq__53=NULL,#p__linq__54=NULL,#p__linq__55=NULL,#p__linq__56=NULL,#p__linq__57=1,#p__linq__58='00000000-0000-0000-0000-000000000000',#p__linq__59='00000000-0000-0000-0000-000000000000',#p__linq__60='00000000-0000-0000-0000-000000000000'
I'm sure there must be a way to get Linq to generate more friendly SQL. If I wrote this same query it could be done in about 5 joins and no inner selects, is it possible to get Linq to tidy this up?
Thanks
Gavin
The large query LINQ to EF creates is just a shortcoming of the first release of the Entity Framework. However, your query contains the phrase .OrderBy(SortField + " " + SortOrder), I believe the preffered way to write this would be .OrderBy(SortField).ThenBy(SortOrder). Also, is there any reason that you are using | instead of || and & instead of && in some places?
IQueryable<Tasks> tl = db.Tasks
.Include("Catagories")
.Include("Projects")
.Include("TaskStatuses")
.Include("AssignedTo")
.Where
(t => (t.TaskStatuses.TaskStatusId.Equals(currentStatus) | currentStatus == -1) &
(t.Projects.ProjectId.Equals(projectId) | projectId == -1) &
(t.Subject.Contains(SearchText) | t.Description.Contains(SearchText) | SearchText == "" | SearchText == null) &
(t.Projects.Active == true) &
(t.Catagories.Active == true || t.Catagories==null) &
(t.LoggedBy.UserProfile.Companies.CompanyId == CompanyId) &
(assignedToGuid == rnd | t.AssignedTo.UserId.Equals(assignedToGuid))).OrderBy(SortField + " " + SortOrder);

Resources