Linq to entity - Join with multiple contidions - entity-framework

I`m using Entity Framwork and i have the next projection:
var items = from mapsDsc in DbContext.MapsDesc
join mapCat in DbContext.MapsCategories on mapsDsc.MapID equals mapCat.MapID
join mainCat in DbContext.MainCategories on mapCat.MainCategory equals mainCat.MainCatID
join subCat in DbContext.SubCategories on mapCat.SubCategory equals subCat.SubCatID
select new DataModel.ComplexEntities.MapsDescExt
{
MapID = mapsDsc.MapID,
MapName = mapsDsc.MapName,
MapLink = mapsDsc.MapLink,
Note = mapsDsc.Note,
MainCategoryID = mapCat.MainCategory,
MainCategoryName = mainCat.Category,
SubCategoryID = mapCat.SubCategory,
SubCategoryName = subCat.Category
};
Please notice that this projection filling strong type and not anonymous one.
I need to customize this projection a little bit but i don`t know how.
At my last join i need to implement the next condition with "or" operator:
join subCat in DbContext.SubCategories on mapCat.SubCategory equals subCat.SubCatID or subCat.SubCatID equals "0"
How can I do it? All the exampels I seen relate to anonymous types and it`s not good for me.
Thanks

You don't have to use the join syntax, you can do the same by a manual where and then slip in an extra condition:
var items = from mapsDsc in DbContext.MapsDesc
join mapCat in DbContext.MapsCategories on mapsDsc.MapID
equals mapCat.MapID
join mainCat in DbContext.MainCategories on mapCat.MainCategory
equals mainCat.MainCatID
from subCat in DbContext.SubCategories
/* here */ where mapCat.SubCategory == subCat.SubCatID || subCat.SubCatID == "0"
select new DataModel.ComplexEntities.MapsDescExt
{
...
(Note that mapCat.SubCategory should be an id field, you probably know which).

Related

Implementing Concat + RANK OVER SQL Clause in C# LINQ

I need to implement the following T-SQL clause ....
SELECT
CONCAT( RANK() OVER (ORDER BY [Order].codOrder, [PackedOrder].codPackedProduct ), '/2') as Item,
[Order].codOrder as [OF],
[PackedOrder].codLine as [Ligne],
[PackedOrder].codPackedProduct as [Material], ----------------------
[Product].lblPProduct as [Product],
[PackedProduct].lblPackedProduct as [MaterialDescription],
[PackedOrder].codPackedBatch as [Lot],
[Product].codCustomerColor as [ReferenceClient],
[PackedOrder].nbrPackedQuantity as [Quantity],
[PackedOrder].nbrLabelToPrint as [DejaImprime]
FROM [Order] INNER JOIN PackedOrder
ON [Order].codOrder = PackedOrder.codOrder INNER JOIN Product
ON [Order].codProduct = Product.codProduct INNER JOIN PackedProduct
ON PackedOrder.codPackedProduct = PackedProduct.codPackedProduct
Where [Order].codOrder = 708243075
So Far, I'm able to do:
var result =
from order1 in Orders
join packedorder1 in PackedOrders on order1.codOrder equals packedorder1.codOrder
join product1 in Products on order1.codProduct equals product1.codProduct
join packedproduct1 in PackedProducts on packedorder1.codPackedProduct equals packedproduct1.codPackedProduct
where order1.codOrder == _order.codOrder
select new FinishedProductPrintingM
{
OF = order1.codOrder,
Ligne = packedorder1.codLine,
Material = packedorder1.codPackedProduct,
Produit = product1.codProductType,
MaterialDescription = packedproduct1.lblPackedProduct,
Lot = packedorder1.codPackedBatch,
RéférenceClient = product1.codCustomerColor,
Quantité = packedorder1.nbrPackedQuantity,
Déjàimprimé = packedorder1.nbrLabelPrinted
};
Please let me know if its possible or not. I need to display the Items in such a way.Please feel free to add your valuable comments.
I am not aware how to use concat and Rank over function in LINQ.
Can anyone help me to convert my SQL query into LINQ?

How to convert this to LINQ OR EF

SELECT EquipmentSerials.SerialNo,EquipmentSerials.IDNo,Equipments.Name,Equipments.TechOrder,Equipments.WorkUnitCode,Equipments.NationalStockNumber,Equipments.Manufacturer,Equipments.PartNumber,EquipmentSerials.ID,EquipmentSerials.EquipmentID,Discrepancy.Symbol
FROM EquipmentSerials
INNER JOIN Equipments ON (EquipmentSerials.EquipmentID = Equipments.ID)
INNER JOIN Discrepancy ON (EquipmentSerials.ID = Discrepancy.EquipmentSerialsID)
WHERE Discrepancy.Symbol='-'
Can anyone convert this to EF?
Thanks
Please try this
var data= from EquipmentSerials in db.EquipmentSerials
join Equipments in db.Discrepancy on EquipmentSerials.EquipmentID equals Equipments.ID
join Discrepancy in db.Discrepancy on EquipmentSerials.ID equals Discrepancy.EquipmentSerialsID
where Discrepancy.Symbol == "-"
select new {
EquipmentSerials.SerialNo,EquipmentSerials.IDNo,Equipments.Name,Equipments.TechOrder,Equipments.WorkUnitCode,Equipments.NationalStockNumber,Equipments.Manufacturer,Equipments.PartNumber,EquipmentSerials.ID,EquipmentSerials.EquipmentID,Discrepancy.Symbol};

LINQ from objects Left Join

I have a linq query that works fine when I join two tables, but when I include another table, it does not return data. Please help me figure out what I am doing wrong.
First Linq returns data:
var q = (from c in _context.Complaint
join cl in _context.Checklist on c.COMP_ID equals cl.COMP_ID into clleft
from cls in clleft.DefaultIfEmpty()
orderby c.timestamp descending
select new
{
FileNum = c.FileNum
}).AsQueryable().Distinct();
return q;
When I add this table, no data returns
var q = (from c in _context.Complaint
join cl in _context.Checklist on c.COMP_ID equals cl.COMP_ID into clleft
from cls in clleft.DefaultIfEmpty()
join oim in _context.OIM_EMPLOYEE on cls.MonitorEnteredEmpID equals oim.EmpID into oimleft
from oims in oimleft.DefaultIfEmpty()
orderby c.timestamp descending
select new
{FileNum = c.FileNum
}).AsQueryable().Distinct();
return q;

how to flatten out webapi EF using DTO and linq

I am trying to flatten out my webapi EF using a DTO and linq but not quite sure how to do it. My end goal is to say, I want to return ALL four accounts where USERNAME = x.
In this example there is 1 username with access to 1 client, and that 1 client has 4 accounts.
How can I make the result come back with 4 entries, 1 for each account?
Here is what I have so far...
var x2 = from b in db.AspNetUsers
where b.UserName == username
select new AspNetUserDetailDTO()
{
UserName = b.UserName,
Email = b.Email,
Mapping_UserClient = b.Mapping_UserClient
//ClientName = b.Mapping_UserClient.SelectMany<Mapping_UserClient>(x => x.ClientID)
//Mapping_UserClient = b.Mapping_UserClient
};
below is my sql diagram.
so I tried writing a plain sql query to return a basic result of what I am looking for... now I do not know how to do this in LINQ
SELECT
dbo.Clients.ClientName
,dbo.Mapping_UserClient.ClientID
,*
FROM [xxx].[dbo].[AspNetUsers]
inner join dbo.Mapping_UserClient on dbo.Mapping_UserClient.AspNetUsersID = dbo.AspNetUsers.Id
inner join dbo.Clients on dbo.Clients.ClientID = dbo.Mapping_UserClient.ClientID
inner join dbo.Mapping_ClientAccount on dbo.Mapping_ClientAccount.ClientID = dbo.Clients.ClientID
inner join dbo.Accounts on dbo.Accounts.AccountID = dbo.Mapping_ClientAccount.AccountID
where Email = 'dddd'
Translating your query above, you would get something like this in Linq:
var query = (from acc in db.Accounts
join mca in db.Mapping_ClientAccount
on acc.AccountId equals mca.ClientID
join cli in db.Clients
on mca.ClientID equals cli.ClientID
join muc in db.Mapping_UserClient
on cli.ClientID equals muc.ClientID
join anu in db.AspNetUsers
on muc.AspNetUsersID equals anu.Id
where anu.UserName == username
select new AspNetUserDetailsDTO()
{
ClientName = cli.ClientName,
ClientID = cli.ClientID
}).ToList();

Linq: the linked objects are null, why?

I have several linked tables (entities). I'm trying to get the entities using the following linq:
ObjectQuery<Location> locations = context.Location;
ObjectQuery<ProductPrice> productPrice = context.ProductPrice;
ObjectQuery<Product> products = context.Product;
IQueryable<ProductPrice> res1 = from pp in productPrice
join loc in locations
on pp.Location equals loc
join prod in products
on pp.Product equals prod
where prod.Title.ToLower().IndexOf(Word.ToLower()) > -1
select pp;
This query returns 2 records, ProductPrice objects that have linked object Location and Product but they are null and I cannot understand why. If I try to fill them in the linq as below:
res =
from pp in productPrice
join loc in locations
on pp.Location equals loc
join prod in products
on pp.Product equals prod
where prod.Title.ToLower().IndexOf(Word.ToLower()) > -1
select new ProductPrice
{
ProductPriceId = pp.ProductPriceId,
Product = prod
};
I have the exception "The entity or complex type 'PBExplorerData.ProductPrice' cannot be constructed in a LINQ to Entities query"
Could someone please explain me what happens and what I need to do?
Thanks
The answer to your first question the Product and Location are null because you need to add an Include("") to your query.
IQueryable<ProductPrice> res1 = from pp in
productPrice.Include("Location").Include("Product")
join loc in locations
on pp.Location equals loc
join prod in products
on pp.Product equals prod
where prod.Title.ToLower().IndexOf(Word.ToLower()) > -1
select pp;
The second issue is EF is trying to push down your query and ProductPrice (is not an entity) so it can not. If you want to do this convert it to an anonymous type so just do
select new
{
ProductPriceId = pp.ProductPriceId,
Product = prod
};
And then do
res.ToList().ConvertAll(x=new ProductPrice () {
ProductPriceId = x.ProductPriceId ,
Product = x.Product
});
Or you could do it other ways, by selecting the entity you want, and just populating manual.