LINQ very SLOW when making .toList() - linq

I'm with a problem i can't solve,
I'm making a simple query in linq:
List<MOV> mvs = (from x in new MyAppDataContextSingleton().DataContext.MOV
where x.dateMOV.GetValueOrDefault(x.dateCriation).Date >= initialDate.Date && x.dateMOV.GetValueOrDefault(x.dateCriation).Date <= finalDATE.Date
orderby x.dateMOV
select x).ToList();
Execute this query directly on SQL is very fast, it only return about 20 results!
When i execute this query on my project using LINQ is very very slow taking more that 20 seconds :\ but this problem only happens when executing the query to this table. Any idea about what's happening? and how can i solve it?
Best regards,
André

Try turning off Deferred Loading:
db.DeferredLoadingEnabled = false;
http://msdn.microsoft.com/en-us/library/Bb386920(v=vs.100).aspx

Related

How to write good LINQ query for this?

I have a LINQ Query. When i run the query it takes so much of time to perform the operation. How can i modify the query to perform good. here is the LINQ query.
Query
var model = (from items in Db.Items
where items.ItemNo == DD.ItemNumber
select new ViewModel()
{
INo = items.ItemNo,
BTags = (from asd in Db.BibContents where asd.BibId == items.BibId && asd.TagNo == "245" && asd.Sfld == "a" select asd.Value).FirstOrDefault(),
Sid = (from stat in Db.ItemStatus1 where stat.Id == items.StatusId select stat.Description).FirstOrDefault(),
Option = DD.Option
}).ToList();
You should analyze the query in SQL Profiler and Query Analyzer. The problem is probably indexes on your tables.
First of all, while your query is always working with database objects, you'd better do all your job in SQL and bring only the results to LINQ.
This will probably improve your performance.
Make sure EF is not causing a Select N+1 problem.
http://blogs.microsoft.co.il/blogs/gilf/archive/2010/08/18/select-n-1-problem-how-to-decrease-your-orm-performance.aspx

Performance Question between two Linq Queries in LinqPad and in Practice

I have a query:
(from sr in ctx.STARS_Route
where sr.STARS_RouteStopDestination.Any(i => i.IsWorkingSet == true && i.STARS_DistrictRoute.DistrictId == districtId) == true
select sr.DistrictRouteNumber).Distinct();
In LinqPad the query was running at roughly 0.3 seconds. There are roughly 800K records in the STARS_RouteStopDestination table, but the average return is about 30-90 records.
In practice, the method returning the results from this query was taking 4+ seconds! It didn't make any sense.
The only thing I could think of is that the .Any clause was taking a lot of time, but LinqPad said the query was fast. I set up a test (please forgive the names):
using (STARSEntities ctx = new STARSEntities())
{
var Original = (from sr in ctx.STARS_Route
where sr.STARS_RouteStopDestination.Any(i => i.IsWorkingSet == true && i.STARS_DistrictRoute.DistrictId == districtId) == true
select sr.DistrictRouteNumber).Distinct();
var Entity = (from rsd in ctx.STARS_RouteStopDestination
where rsd.STARS_DistrictRoute.DistrictId == districtId
&& rsd.IsWorkingSet == true
select rsd.STARS_Route.DistrictRouteNumber).Distinct();
DateTime startOriginal = DateTime.Now;
routes = Original.ToList();
Debug.WriteLine("Original took: " + (DateTime.Now - startOriginal).ToString());
DateTime startEtity = DateTime.Now;
routes = Entity.ToList();
Debug.WriteLine("Entity took: " + (DateTime.Now - startEtity).ToString());
}
The output blew my mind:
Original took: 00:00:04.0270000
Entity took: 00:00:00.0200000
Why does the query with the .Any clause take so much longer to run, and why would LinqPad say that the Original query runs slightly faster than the Entity query against the same dataset?
You are simply acting upon two different objects that has two different strategies of obtaining the result. LINQPad generates a LINQ to SQL model and injects your code into a method with this model in scope.
Your STARSEntities class is of a different type and probably has a completely different interaction with the database.
LINQPad has its own view that displays the SQL being run. You should compare it to the SQL being executed by the EF model. This is displayed in the SQL Server Profiler when you execute.

Why does LINQ Date Column comparison not work?

For a LINQ query like:
var entities = from Account p in context.Accounts
where p.LastTimeServerSettingsChanged > p.LastTimeDeviceConnected
select p;
the query that is generated is:
SELECT
[Extent1].[Username] AS [Username],
[Extent1].[LastTimeDeviceConnected] AS [LastTimeDeviceConnected],
[Extent1].[LastTimeServerSettingsChanged] AS [LastTimeServerSettingsChanged]
FROM [dbo].[Account] AS [Extent1]
WHERE [Extent1].[LastTimeServerSettingsChanged] > [Extent1].[LastTimeDeviceConnected]
And this does not work (no results).
And the following also generates the same SQL (hence no results also)
var entities = context.Accounts.Where(k => k.LastTimeServerSettingsChanged > k.LastTimeDeviceConnected).Select(k => k);
My question is why, and how can this query be performed (using LINQ)?
The above code works fine. I was hitting the wrong database and hence was getting the wrong result. GIGO. QED.

Linq filter collection with EF

I'm trying to get Entity Framework to select an object and filter its collection at the same time. I have a JobSeries object which has a collection of jobs, what I need to do is select a jobseries by ID and filter all the jobs by SendDate but I can't believe how difficult this simple query is!
This is the basic query which works:
var q = from c in KnowledgeStoreEntities.JobSeries
.Include("Jobs.Company")
.Include("Jobs.Status")
.Include("Category")
.Include("Category1")
where c.Id == jobSeriesId
select c;
Any help would be appreciated, I've been trying to find something in google and what I want to do is here:http://blogs.msdn.com/bethmassi/archive/2009/07/16/filtering-entity-framework-collections-in-master-detail-forms.aspx
It's in VB.NET though and I couldn't convert it to C#.
EDIT: I've tried this now and it doesn't work!:
var q = from c in KnowledgeStoreEntities.JobSeries
.Include("Jobs")
.Include("Jobs.Company")
.Include("Jobs.Status")
.Include("Category")
.Include("Category1")
where (c.Id == jobSeriesId & c.Jobs.Any(J => J.ArtworkId == "13"))
select c;
Thanks
Dan
Include can introduce performance problems. Lazy loading is guaranteed to introduce performance problems. Projection is cheap and easy:
var q = from c in KnowledgeStoreEntities.JobSeries
where c.Id == jobSeriesId
select new
{
SeriesName = c.Name,
Jobs = from j in c.Jobs
where j.SendDate == sendDate
select new
{
Name = j.Name
}
CategoryName = c.Category.Name
};
Obviously, I'm guessing at the names. But note:
Filtering works.
SQL is much simpler.
No untyped strings anywhere.
You always get the data you need, without having to specify it in two places (Include and elsewhere).
No bandwith penalties for retrieving columns you don't need.
Free performance boost in EF 4.
The key is to think in LINQ, rather than in SQL or in materializing entire entities for no good reason as you would with older ORMs.
I've long given up on .Include() and implemented Lazy loading for Entity Framework

How to write dynamic Linq2Sql compiled queries?

I'm having performance issues with Linq2Sql compared to raw ADO.NET which has led me down the path of compiled queries. I have got this far so far
public static readonly Func<MyDataContext, WebServices.Search.Parameters, IQueryable<image>>
Compiled_SelectImagesLinq =
CompiledQuery.Compile<MyDataContext, WebServices.Search.Parameters, IQueryable<image>>(
(dc, parameters) => from i in dc.images
join l in dc.links on i.image_id equals l.image_id
join r in dc.resolutions on i.image_id equals r.image_id
where i.image_enabled == true && i.image_rating >= parameters.MinRating
&& i.image_rating <= parameters.MaxRating
select i
);
However I can't figure out how to add the extra optional parameters to the query as I currently do
if (parameters.Country != null)
{
query = query.Where(x => x.image_country_id == parameters.Country);
}
if (parameters.ComponentId != null)
{
query = query.Where(x => x.links.Any(l => l.link_component_id == parameters.ComponentId));
}
etc, etc
I tried writing another function which does
var query = Compiled_SelectImagesLinq(parameters);
and then adding the extra parameters to the query and returning
return query.Distinct().Take(parameters.Results);
Bit this doesn't seem right and returns no results
Have a look at this article. It may not do what you need (especially since you are compiling your queries), but anytime someone mentions Dynamic and Linq in the same sentence, I refer them to this article:
Dynamic LINQ: Using the LINQ Dynamic Query Library
http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
You'd have to benchmark your specific query, but often queries must be used 10-20 times before compiled query performance improvements equal the overhead. Also, how are you adding parameters to the where clause?
Additionally, dynamic compiled queries seems a bit of a mismatch. The Dynamic LINQ query library will do what you need but I don't think you'll get the compiled query performance improvement you want.

Resources