Is there anyway to return int and null with nested conditions? - linq

I want to return a customer which is in this city and buy ItemID = 1, 2 or NULL
List<int?> AcceptableValues = new List<int?>
{
1,2
};
List<Customer> Customers = ListOfCustomer.Where(x => x.CountryTbl.City == 1
&& x.ItemTbl.Any(p => p.ItemID == 1 || p.ItemID ==2 || p.Item is null)
&& x.SellTbl.SellType == 10).ToList();
Is there any way we can use LINQ to filter the customer who only buys itemID in the AcceptableValues ?
I've tried with ItemTbl.SingleOrDefault, or ItemTbl.Where, or AppeptableValues.Contains(m => m.ItemID) but didn't work.

List<Customer> Customers = ListOfCustomer
.Where(c => c.CountryTbl.City == 1
&& c.ItemTbl.Any(i => i.ItemID == null || AcceptableValues.Contains(i.ItemID))
&& c.SellTbl.SellType == 10).ToList();

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.

LINQ with Lambda Expressions

How can I convert the LINQ query below using LAMBDA Expressions ?
var select = from si in db.San_Imovel
join sic in db.San_Imovel_caracteristica
on si.Imovel_Id equals Convert.ToInt64(sic.Imovel_Id)
join sf in db.San_Filial
on si.Credenciada_Id equals sf.Credenciada_Id
where si.Credenciada_Id == credenciada_Id
&& (si.GrupoImovel_Id.ToString().Contains("1") || si.GrupoImovel_Id.ToString().Contains("2"))
&& (si.Status_Id.ToString().Contains("1") || si.Status_Id.ToString().Contains("12"))
&& si.NomeArquivo != null
&& (si.Imovel_Id.ToString().Contains(""))
select new
{
si.Celula_Id,
si.Credenciada_Id,
si.Imovel_Id,
si.NomeArquivo,
si.TipoDsc1,
si.BairroDsc1,
si.AreaRealPrivativa,
sic.VagasGaragem,
si.ValorImovel,
si.ValorCondominio,
si.ValorIPTU,
si.Lat2,
si.Lon2,
sf.ApelidoCredenciada,
sf.ddd,
sf.TelefoneVenda,
sf.TelefoneLocacao,
sf.Email,
si.Bairro1,
si.NomeCidade,
si.Transacao_ID
};
var query =
db.San_Imovel
.Join(db.San_Imovel_caracteristica,
si => Imovel_Id,
sic => Convert.ToInt64(sic.Imovel_Id),
(si, sic) => new { si, sic })
.Join(db.San_Filial,
x => x.si.Credenciada_Id,
sf => sf.Credenciada_Id,
(x, sf) => new { x.si, x.sic, sf })
.Where(x => x.si.Credenciada_Id == credenciada_Id &&
(x.si.GrupoImovel_Id.ToString().Contains("1") ||
x.si.GrupoImovel_Id.ToString().Contains("2")) &&
(x.si.Status_Id.ToString().Contains("1") ||
x.si.Status_Id.ToString().Contains("12")) &&
x.si.NomeArquivo != null &&
(x.si.Imovel_Id.ToString().Contains(""))
.Select(x => new {
x.si.Celula_Id,
x.si.Credenciada_Id,
x.si.Imovel_Id,
x.si.NomeArquivo,
x.si.TipoDsc1,
x.si.BairroDsc1,
x.si.AreaRealPrivativa,
x.sic.VagasGaragem,
x.si.ValorImovel,
x.si.ValorCondominio,
x.si.ValorIPTU,
x.si.Lat2,
x.si.Lon2,
x.sf.ApelidoCredenciada,
x.sf.ddd,
x.sf.TelefoneVenda,
x.sf.TelefoneLocacao,
x.sf.Email,
x.si.Bairro1,
x.si.NomeCidade,
x.si.Transacao_ID
});
BTW you don't need to convert whole query to method syntax. You can convert only filtering where part.

Linq join with exists

I'm busy rewriting a system and are using Linq queries to extract data from the database. I am used to plain old TSQL and stored procedures so my Linq skills are not the best.
I have a sql query that I try to rewrite in Linq that contains a join, where clause and IN statements. I do get it right but when I run the sql query I get a different value as from the Linq query. Somewhere I'm missing something and can't find the reason.
Here is the SQL:
select
isnull(Sum(QtyCC) + Sum(QtyEmployee), 0) *
isnull(Sum(UnitPrice), 0)[TotalRValue]
from
tbl_app_KGCWIssueLines a
inner join tbl_app_KGCWIssue b on b.IssueNrLnk = a.IssueNrLnk
where
b.CreationDate >= '2011-02-01' and
a.IssueNrLnk IN (
select
IssueNrLnk
from
tbl_app_KGCWIssue
where
CustomerCode = 'PRO002' and
ISNULL(Tier1,'') = 'PRO002' and
ISNULL(Tier2,'') = 'HAMD01' and
ISNULL(Tier3,'') = '02' and
ISNULL(Tier4,'') = '02001' and
ISNULL(Tier5,'') = 'PTAHQ001' and
ISNULL(Tier6,'') = '035' and
ISNULL(Tier7,'') = '' and
ISNULL(Tier8,'') = '' and
ISNULL(Tier9,'') = '' and
ISNULL(Tier10,'') = ''
)
And here is the Linq:
ctx.ObjectContext.tbl_app_KGCWIssue
.Join(ctx.ObjectContext.tbl_app_KGCWIssueLines,
i => i.IssueNrLnk, l => l.IssueNrLnk, (i, l) => new { i, l })
.Where(o => o.i.CreationDate >= IntervalStartDate)
.Where(p => ctx.ObjectContext.tbl_app_KGCWIssue
.Where(a =>
a.CustomerCode == CustomerCode &&
a.Tier1 == employee.Tier1 &&
a.Tier2 == employee.Tier2 &&
a.Tier3 == employee.Tier3 &&
a.Tier4 == employee.Tier4 &&
a.Tier5 == employee.Tier5 &&
a.Tier6 == employee.Tier6 &&
a.Tier7 == employee.Tier7 &&
a.Tier8 == employee.Tier8 &&
a.Tier9 == employee.Tier9 &&
a.Tier10 == employee.Tier10)
.Select(i => i.IssueNrLnk)
.Contains(p.l.IssueNrLnk))
.Sum(p => p.l.UnitPrice * (p.l.QtyEmployee + p.l.QtyCC));

linq query, search by max date if previous date exists

I'm trying to get three columns back from the database, DecalExpireDate, DecalExpireMonth and DecalExpireYear. Basically, I'm trying to check if it has a previous expiration date and if it does, I need to get the latest expiration date, as it may have multiple previous expiration dates.
var previousExpirationDate = (from d in db.CT_Decals
where d.TankID == decal.TankID
&& d.DecalStatus == "Approved"
&& d.DecalExpireDate == ((from dn in db.CT_Decals
where dn.TankID == decal.TankID
&& dn.DecalStatus == "Approved"
select dn.DecalExpireDate).Max())
select new
{
d.DecalExpireDate,
d.DecalExpireMonth,
d.DecalExpireYear
});
This query isn't working, can anybody see the problem? I'm searching by TankID, Status = approved and then I try to use the max expirationDate.
How about this
var result = db.CT_Decals.Where(o => o.TankId == decal.TankId && o.DecalStatus == "Approved")
.OrderByDescending(o => o.DecalExpireDate)
.Select(o => new { o.DecalExpireDate,
o.DecalExireMonth,
o.DecalExireYear }).First()
or
var result = (from d in db.CT_Decals
where d.TankID == 1 && d.Status == "Approved"
orderby d.ExpireDate descending
select new { d.DecalExpireDate,
d.DecalExpireMonth,
d.ExpireDate }).First();
The problem it's with the that max function couldn't be translated to Sql in the scope that you need so you could try like this
var previousExpirationDate = (from d in db.CT_Decals
where d.TankID == decal.TankID
&& d.DecalStatus == "Approved"
&& d.DecalExpireDate == ((from dn in db.CT_Decals
where dn.TankID == decal.TankID
&& dn.DecalStatus == "Approved"
order by dn.DecalExpireDate
select dn.DecalExpireDate).First())
select new
{
d.DecalExpireDate,
d.DecalExpireMonth,
d.DecalExpireYear
});
Although Max may be the problem in your example, it would be nice to find a way to use it properly because it is faster than sorting. How about:
Edit: this answer only returns the DecalExpireDate
var previousExpirationDate = (from d in db.CT_Decals
where d.TankID == decal.TankID
&& d.DecalStatus == "Approved"
select new
{
d.DecalExpireDate,
d.DecalExpireMonth,
d.DecalExpireYear
}).Max(d => d.DecalExpireDate);
For this version you will have to test to see if it's worth making an extra call to the database to avoid sorting:
var latestDate = (from d in db.CT_Decals
where d.TankID == decal.TankID
&& d.DecalStatus == "Approved"
select d.DecalExpireDate).Max();
var previousExpirationDate = (from d in db.CT_Decals
where d.TankID == decal.TankID
&& d.DecalStatus == "Approved"
&& d.DecalExpireDate == latestDate
select new
{
d.DecalExpireDate,
d.DecalExpireMonth,
d.DecalExpireYear
}).First();

LINQ Join Errors

I'm getting the following error:
The type of one of the expressions in the join clause is incorrect. Type inference failed in the call to 'Join'.
when using the code below
var ccrCodes = (from c in db.CCRCodes
join i in items on
new { c.baan_cat_fam_code, c.baan_cat_code } equals
new { i.baan_cat_family_code, i.baan_cat_code }
where i => i.contact_dt.Value.Year == date.Year && i.contact_dt.Value.Month == date.Month
select c).Distinct().OrderBy(c => c.code_desc);
What I'm trying to do in LINQ is create a multi-condition join and am running into problems. Any ideas?
Thanks,
Try giving names to the properties in your anonymous objects:
var ccrCodes = (from c in db.CCRCodes
join i in items on
new { FamCode = c.baan_cat_fam_code, CatCode = c.baan_cat_code } equals
new { FamCode = i.baan_cat_family_code, CatCode = i.baan_cat_code }
where i => i.contact_dt.Value.Year == date.Year && i.contact_dt.Value.Month == date.Month
select c).Distinct().OrderBy(c => c.code_desc);
EDIT: Alright, I have to confess, I am no expert on query syntax, but you want to filter the 'items' list before doing the join, like the following fluent version of your query:
db.CCRCodes
.Join(
items.Where(i => i.contact_dt.Value.Year == date.Year && i.contact_dt.Value.Month == date.Month),
x => new { FamCode = x.baan_cat_fam_code, CatCode = x.baan_cat_code },
x => new { FamCode = x.baan_cat_family_code, CatCode = x.baan_cat_code },
(o,i) => o
).Distinct().OrderBy(c => c.code_desc)
ANOTHER EDIT: Per Ahmad's suggestion:
var ccrCodes = (from c in db.CCRCodes
join i in items.Where(x => x.contact_dt.Value.Year == date.Year && x.contact_dt.Value.Month == date.Month) on
new { FamCode = c.baan_cat_fam_code, CatCode = c.baan_cat_code } equals
new { FamCode = i.baan_cat_family_code, CatCode = i.baan_cat_code }
select c).Distinct().OrderBy(c => c.code_desc);
YET ANOTHER EDIT: Per another Ahmad suggestion:
var ccrCodes = (from c in db.CCRCodes
from i in items
where i.contact_dt.Value.Year == date.Year && i.contact_dt.Value.Month == date.Month
&& c.baan_cat_fam_code == i.baan_cat_family_code && c.baan_cat_code == i.baan_cat_code
select c).Distinct().OrderBy(c => c.code_desc);

Resources