Disclaimer: By and beyond Linq to Database we understand the most common .NET libraries for accessing relational databases using Linq queries. Such as Linq2SQL, Entity Framework, NHibername, Linq2db and the likeSince the advent of IQueryable providers to access databases, writing queries has become much easier. On the one hand, this is good, because applications have become much easier to do. On the other hand, the quality of requests fell dramatically. And the point is not that providers generate bad SQL, but that people write queries, not understanding how it works under the hood. For many C # programmers,
IQueryable
is magic, and there is a natural desire to reduce the effect of magic on applications, to isolate magic from the rest of the code. Such an approach not only does not correct the situation, but exacerbates it ... public IEnumerable<DocumentDto> GetDocumentsToday() { foreach (var item in Db.Documents.Where(x => EntityFunctions.TruncateTime(x.CreatedOn) == DateTime.Today)) { yield return Mapper.Map<Document, DocumentDto>(item); } }
IQueryable
providers from the consumer. But this, seemingly simple, code contains 3 bad things when working with Linq to Database.DataReader
open while the IQueryable
is being enumerated. This leads to the fact that all resources allocated by the server for this request are retained until the end of the crawl and the closure of the DataReader
. In this example, another yield return
is used, that is, the processing of each element can take a very long time..Load()
or .ToList()
or .ToArray()
. If the query results are very large, and you need to involve everything, then it is best to organize paging blocks that do not cause escalation of locks. ... WHERE cast(CreatedOn as Date) = cast(GETDATE() as Date)
Naturally, no index can optimize such a sample and there will be a complete crawl of the table. Db.Documents.Where(x => x.CreatedOn >= DateTime.Today && x.CreatedOn < DateTime.Today.AddDays(1))
Now you can make an index on the field CreatedOn
. public IEnumerable<DocumentDto> GetDocumentsToday() { return Db.Documents .Where(x => x.CreatedOn >= DateTime.Today && x.CreatedOn < DateTime.Today.AddDays(1)) .Select (x => new DocumentDto {...}) .ToList(); }
You can also correct the Mapper
class so that it generates projections.Source: https://habr.com/ru/post/230479/
All Articles