EF core .any not filtering results - entity-framework

I have the following sql, which I'm trying to translate to linq:
SELECT *
FROM [Service] s
inner join vendor v on vendorid=v.id
inner join VendorLocation vl on vl.VendorId=v.id
where s.active=1 and v.active=1 and vl.City = 'toronto' and vl.Active=1
I have a Service that belongs to a Vendor and the Vendor has Locations. I'm trying to filter the locations based on city, but the query returns results that don't satisfy the conditions in the ".Any" clause
var service = await _context.Service
.Where(s => s.Active && s.Vendor.Active)
.Include(s => s.Vendor)
.ThenInclude(s => s.VendorLocations)
.Where(s => s.Vendor.VendorLocations.Any(l => l.City == City && l.Active))
.ToListAsync();
The sql statement returns the correct results but the linq is not.
Any help is appreciated, thanks! Ben

You can try with query notation:
var query = from v in _context.Vendors
join s in v.Services on v.Id equals s.VendorId
join l in v.ServiceLocations on v.Id equals l.VendorId
where v.Active && s.Active && l.City=="Toronto"
select new {v,s,l};
var result= await query.ToLinqAsync();

Hi your using EF Core now , But
I suggest Use LINQ because its simplest
Please read this page for more
and this is sample code
var innerGroupJoinQuery2 =
from category in categories
join prod in products on category.ID equals prod.CategoryID into prodGroup
from prod2 in prodGroup
where prod2.UnitPrice > 2.50M
select prod2;

the query returns results that don't satisfy the conditions in the ".Any" clause
Those queries just aren't the same. The SQL Query returns one row per VendorLocation with additional columns from joined tables, and projects all the columns.
SELECT *
FROM [Service] s
inner join vendor v on vendorid=v.id
inner join VendorLocation vl on vl.VendorId=v.id
where s.active=1 and v.active=1 and vl.City = 'toronto' and vl.Active=1
In LINQ this would be something like
from vl in VendorLocation
where vl.Vendor.Active
&& vl.Vendor.Service.Active
&& vl.Active
&& vl.City = 'toronto'
select new
{
ServiceName = vl.Vendor.Service.Name,
ServiceDescription = vl.Vendor.Service.Description,
. . .
VendorName = vl.Vendor.Name,
VendorWhatever = vl.Vendor.Whatever,
. . .
vl.Name,
. . .
};

Related

Entity Framework Core Count unrelated records in another table

I need to count how many records in the tableA are not in the tableA, how to do this with LINQ?
with SQL I do the following way
select count(*) as total from produtoitemgrade g
where g.id not in (select idprodutograde from produtoestoque where idProduto = 12)
and g.idProduto = 12
my linq code so far.
var temp = (from a in Produtoitemgrades
join b in Produtoestoques on a.IdUnico equals b.IdUnicoGrade into g1
where g1.Count(y => y.IdProduto == 12)>0 && !g1.Any()
select a).ToList();
I tried to follow that example LINQ get rows from a table that don't exist in another table when using group by?
but an error occurs when running, how can I do this?
Thanks!
Your query should looks like the following, if you want to have the same SQL execution plan:
var query =
from a in Produtoitemgrades
where !Produtoestoques.Where(b => a.IdUnico == b.IdUnicoGrade && b.idProduto == 12).Any()
&& a.idProduto == 12
select a;
var result = query.Count();

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();

sql query into Linq

Please anyone can help me to write this sql query into Linq.
select
P.ID,
P.Name,
Set_selected=
case when exists(
select C.ClassifierID
from dbo.ProductClassifiers C
where C.ProductID=130 and C.ClassifierID=P.ID)
then 'Yes' else 'No' end
from dbo.Classifier P
var retVal = (from s in dataContext.ProductClassifiers
join k in dataContext.Classifier
on s.ClassifierId equals k.Id
where s.ProductId == 30
select new {write here what values you want to get like s.Id,k.Name etc}).ToList();
Here's an attempt:
var query = from p in dataContext.Classifiers
select new {
p.ID,
p.Name,
p.Selected = dataContext.ProductClassifiers
.Where(c => c.ProductID == 130 &&
c.ClassifierID == p.ID)
.Any()
};
(That will make the Selected property Boolean rather than Yes/No, but that's usually going to be easier to work with.)
You should look at what the translated SQL looks like though, and in particular what the query plan is like compared with your original.
Untested, but hopefully works:
var q = classifier.Select(
p => new {
p.ID,
p.Name,
Set_selected = productClassifiers
.Select(c => c.ProductID == 130 && c.ClassifierID == p.ID)
.Any() ? "Yes" : "No"
}
);
The code assumes that you have two IEnumerable<T> representing the Classifier and ProductClassifiers tables.

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.