Linq to entities subquery - entity-framework

How can I write the following subquery in Linq:
Context.Set<Process>()
.Include(...)
.Where(x => x.Activity.Name.CompareTo(Context.Set<Activity>().Where(a => a.Id == activityId).Select(c => a.Name)) > 0)
.Take(1);
This is a simplifed version of query, WHERE clause only includes the part that is not working. If I change Context.Set().... subquery to a string constant, then the query works. As it is, it gives NotSupportedException
LINQ to entities does not recognize method Set<Activity>

Try this:
(from p in context.Set<Process>().Include(...)
from a in context.Set<Activity>()
where a.Id == activityId
where p.Activity.Name.CompareTo(a.Name) > 0
select p).Take(1);

Related

EF Core: Take() also limits results of include

I have following query:
var query = this.DbContext.Products.AsNoTracking()
.WhereIf(publishedFrom.HasValue, x => x.Erscheinen.Value >= publishedFrom)
.WhereIf(publishedTo.HasValue, x => x.Erscheinen.Value < publishedTo)
.WhereIf(!string.IsNullOrEmpty(publisherCode), x=> x.VerlagCode == publisherCode)
.OrderByDescending(x => x.GeplantesErscheinen)
.Take(maxResultCount)
.Include(x => x.SubjectAreas)
.Include(x => x.ProductPrices)
.Include(x => x.ProductOriginators);
;
The query should return the Product-Entity based on 3 where conditions and a order by. Related entities should be included. Afterwards only the First maxResultCount of the product query result should be returned. For the products ALL related entities should be loaded.
HOWEVER, Take() also has an impact on the query of the related entities. When I look into the sql server profiler I see followign query executed:
exec sp_executesql N'SELECT [a0].[ProductId], [a0].[SubjectAreaId], [t].[Id]
FROM (
SELECT TOP(#__p_3) [a].[Id], [a].[GeplantesErscheinen]
FROM [AppProducts] AS [a]
WHERE ((((#__ef_filter__p_0 = CAST(1 AS bit)) OR ([a].[IsDeleted] = CAST(0 AS bit))) AND ([a].[Erscheinen] >= #__publishedFrom_0)) AND ([a].[Erscheinen] < #__publishedTo_1)) AND ([a].[VerlagCode] = #__publisherCode_2)
ORDER BY [a].[GeplantesErscheinen] DESC
) AS [t]
INNER JOIN [AppProductSubjectArea] AS [a0] ON [t].[Id] = [a0].[ProductId]
ORDER BY [t].[GeplantesErscheinen] DESC, [t].[Id]',N'#__p_3 int,#__ef_filter__p_0 bit,#__publishedFrom_0 datetime2(7),#__publishedTo_1 datetime2(7),#__publisherCode_2 nvarchar(4000)',#__p_3=3,#__ef_filter__p_0=0,#__publishedFrom_0='2022-04-22 00:00:00',#__publishedTo_1='2022-07-13 00:00:00',#__publisherCode_2=N'NOM'
Furthermore, I find the generated query very strange, because it also contains the sorting, which I need, however, only for the product.
Can anyone tell me how to get all the related entities without applying the other conditions?

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

EF core .any not filtering results

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,
. . .
};

EF 1.0 flattening a left join query

I'm trying to execute a linq to entites query in (Visual Studio 3.5 /EF 1.0) for 3 entities with the following relationships:
xcCRMCounterparty * => 0..1 CSIDsInUse
CSIDsInUse 1 => * xcCIFToCSID
Previously in T SQL I used:
select distinct CIF, xcCIFToCSID.xcCSID, CounterpartyName
from xcCIFToCSID
left join CSIDsInUse
on xcCIFToCSID.idCSID = CSIDsInUse.Id
left join xcCRMCounterparty
on CSIDsInUse.Id = xcCRMCounterparty.IdCSID
order by CounterpartyName
Now with EF I'm tried to flatten the result set as below, but I don't know how to flatten the xcCRMCounterparty item i.e. it's a collection rather than a single field
var query = from cifto in entities.xcCIFToCSIDSet.Include(x => x.CSIDsInUse).Include(x => x.CSIDsInUse.xcCRMCounterparty)
select new
{
cifto.CIF,
cifto.xcCSID,
cifto.CSIDsInUse.xcCRMCounterparty
};
How can I modify my query so that I can generate flattened results?
Try this:
var query = from cifto in entities.xcCIFToCSIDSet
from x in cifto.CSIDsInUse.xcCRMCouterparty
select new
{
cifto.CIF,
cifto.xcCSID,
x.Name
};

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.