Using EF4. Assume I have this:
IQueryable<ParentEntity> qry = myRepository.GetParentEntities();
Int32 n = 1;
What I want to do is this, but EF can't compare against null.
qry.Where( parent => parent.Children.Where( child => child.IntCol == n ) != null )
What works is this, but the SQL it produces (as you would imagine) is pretty inefficient:
qry.Where( parent => parent.Children.Where( child => child.IntCol == n ).FirstOrDefault().IntCol == n )
How can I do something like the first comparison to null that won't be generating nested queries and so forth?
Try this:
qry.Where( parent => parent.Children.Any( child => child.IntCol == n ));
Any in Linq translates to exists in sql.
If I understood Your queries correctly, this is what You need.
Related
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?
In C# code with EF6 and Sql Server, my goal is to use this query :
Select MAX(columnA) from myTable WHERE columnB>5 AND ColumnC=1
by using C# code.
Example :
SELECT Max(ColumnA) from myTable
becomes :
int max = DbContext.myTable.Max(t => t.ColumnA); => works fine, OK
But do you know how to add the where clause into this C# code ???
Erixx
You put Where first and then Max later like this
int max = DbContext.myTable.Where(it=>it.columnB>5 && it.ColumnC=1).Max(t => t.ColumnA);
Just add the Where before Max (or after, depending on your logic).
int max = DbContext.myTable.Where(t => t.ColumnB > 5 && ColumnC == 1).Max(t => t.ColumnA)
I have a database table with two columns: StartDateTime and FinishDateTime. both are nullable datetime columns.
I'm wanting to calculate the Average time between both fields per row. ie the average duration of my recorded event.
I'm getting a "DbArithmeticExpression arguments must have a numeric common type."
Example EF code with a touch of simplification for the demo.
from p in new DbContext()
where p.user_id = 123
&& p.StartDateTime != null
&& p.FinishDateTime != null
select new {p.StartDateTime, p.FinishDateTime})
.Average(p=> (p.FinishDateTime.Value - p.StartDateTime.Value).Ticks)
I'd love an example of the above, as SQL makes this a breeze.
Its depends on your data provider, it may support DbFunctions and you could do something like this:
(from p in new DbContext()
where p.user_id = 123
&& p.StartDateTime != null
&& p.FinishDateTime != null
select new {p.StartDateTime, p.FinishDateTime})
.Average(x=> DbFunctions.DiffMilliseconds(p.FinishDateTime,p.StartDateTime))
if it doesn't, i think you have to go linq to objects after the select:
(from p in new DbContext()
where p.user_id = 123
&& p.StartDateTime != null
&& p.FinishDateTime != null
select new {p.StartDateTime, p.FinishDateTime})
.ToArray()
.Average(x=> (p.FinishDateTime -p.StartDateTime).Ticks)
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);
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.