SQL Server 2012 introduces a more efficient mechanism for paging using FETCH and OFFSET which could have a big impact on performance of apps which use a lot of paging. Does Entity Framework 5 support this?
So if Im using EF to page using Take + Skip will the LINQ queries be translated into the new 2012 TSQL if EF is targeting SQL Server 2012?
As #Ladislav said, EF 5 doesn't support OFFSET & FETCH. With that said, I wanted to add a bit of perspective. I don't think it should matter much.
When you buy into an ORM like Entity Framework, you're out sourcing your query generation (for perfectly valid reasons). Whether EF uses the 'older' CTE style query with Row_Number() or the newer Fetch / Offset is an implementation detail. Microsoft could update the EF code at any point and change the query generation to use one or the other.
If you want control over the query generation, you either:
Use EF's 'stored procedure mapping' ability
Use stored procedures directly with EF (something I do quite often)
write the ADO/SQL yourself, or
use a more limited micro-orm like massive/PetaPoco
So does it matter?
Well, to a developer writing queries the new syntax is going to be a welcome relief. On the other hand, it doesn't appear that there is a real performance difference between the old CTE method and the new syntax. So from EF's perspective -- not really. We incur a significant overhead using EF, the method of paging probably won't be your break point.
EF 5 doesn't support this feature - actually I think none of SQL Serve 2012 features is available in EF. You can vote for this feature on Data UserVoice to move it up in ADO.NET team product backlog.
Related
I have a small project with inherited C# code, specifically Entity Framework Core. This is hosted in Azure and recently I saw a very interesting feature that I would like to try out: "Automatic Tuning" for the database.
I have a couple of questions regarding this:
Would it conflict with my Entity Framework, as the database objects were originally created from code? My understanding is that it shouldn't, but I would like to be sure.
Is it worth it or anyone had any trouble with it?
Thanks!
Automatic Tuning does not get in conflict in any way with Entity Framework (EF). It just create indexes needed by queries in use on your application. It also drops duplicated and unneeded indexes (but existent unique indexes are not dropped) and chooses the best query plan created by SQL Server. None of these are related to EF.
One thing you need to consider is that Azure SQL Database needs to monitor query activities at least for a day in order to identify some recommendations.
Another thing to take in consideration is that Automatic Tuning does not update statistics and does not defrag indexes.
I would like to ask the Entity Framework Core team what their ambition is for the scope/complexity of query translation compared to EF6.
I've used EF6 extensively and I know that if you can express it in LINQ and don't use any untranslatable functions, EF can probably translate the query correctly.
Will Entity Framework's translation be eventually as good as that, or is that something that is considered secondary, like the lazy loading feature.
If so, about what is the team eventually aiming at compare to EF6?
There's a ticket discussing GroupBy that appears to indicate they deem grouping an advanced type of query, but compared to what EF6 can translate, a normal group-by is pretty average.
(I'm asking here as the EF Core team says on it's site it is monitoring SO for questions.)
We took a very different approach in EF Core. Every LINQ query should work--even if you use untranslatable functions. We do this by translating the parts of the query we can into SQL and processing the rest on the client after the results are returned by the server. As EF Core evolves, we'll translate more and more of the query into SQL (e.g. GROUP BY) which can make it more efficient.
In theory, our goal is to translate everything that the store supports. In some cases however (especially on NoSQL stores) there simply is no translation for a LINQ operator, and we feel it's better to be functional and inefficient than to throw.
If you want to ensure your whole query is translated, you can disable client evaluation. This will cause it to throw like EF6.
I am using Entity Framework 4.1 code first with no stored procedures. And I would like to know a general opinion on the performance of this on huge applications seeing that it generates the SQL in the background. Doesn't this go against best practices of not using stored procedures? How do you fine tune these generated code?
I know you can hack into it to use stored procedures, but is there definately going to be support for stored procedures and the other functions you get with going with the database first option?
Does EF 4.1 have any improvements on the database first option? How would I know if I have the latest version of EF?
The generated SQL is reasonably efficient, but although I've not resorted to SP's as yet, I have written some views (in 4.0) and written LINQ against those in places in order to overcome some performance issues.
Does 4.1 go against best practices of stored procedures ? Well there SP's are best practice for a number of reasons - performance is one, isolation and abstraction of the underlying table structure from your code is another. The performance part of this seems to have been abandoned as "probably not that important these days" for reasons that don't smell 100% to me. And the abstraction issue - well you are using EF Code First for a reason - that reason is that you are looking for a persistence framework for your applications objects: by the very act of choosing EF Code First, you are declaring that you don't want to know how they are stored, in what structures, and what happens to get them back.
How do you tune it ? Mainly by being very careful about lazy loading, by monitoring what's going on at the SQL end (EFProf is one tool, MSSql query profiling works too) and generally by fiddling with things.
To ensure you are running the latest EF (if you have been running the CodeFirst CTP) use the NuGet console and
uninstall-package EFCodeFirst
install-package EntityFramework
4.1 has improvements over 4.0 for database first - namely the lightweight dbContext
EDIT: Adding code as requested...
Simple case
foreach (var order in orders) y=order.orderlines.tolist();
which you fix with
foreach (var order in orders.Include("orderlines").tolist()) y=order.orderlines.tolist();
but less obvious is
foreach (var order in orders.Include("orderlines").tolist()) dothing(order);
where
public void dothing(Orderline ol)
{
if (ol.order.property=true)
....
}
to fix this I think you need
foreach (var order in orders.Include("orderlines.orders").tolist()) dothing(order);
(or better still refactor dothing(Orderline ol) to dothing(Orderline ol, Order ord). My point is that with a local database its incredibly easy to miss these. Its only when you profile the sql, or connect to an SQL database on a slow network (think Azure) or just get serious load, that this begins to hurt!
I am starting with the Entity Framework. It sounds great. But I am wondering if I should watch out for some weakness somewhere. Any experience there?
You probably need to start prefixing these questions with the version you are talking about. A good amount of the annoyances have been fixed in the upcoming version in .NET 4.0.
Here is what I would say after working with the first version for about 6 months using a decent size DB in sql 2k8(40+ tables, several tables with close to 1M rows, and decent amount of traffic)
Lack of Foreign key properties. Meaning if I want to know or work with just the id of a related table I have to load the actual entity. (fixed in next version)
Utter lack of an easy outer join like linq to sql has when using DefaultIfEmpty. Fixed in next version.
Generated Sql is less than optimal This seems to be fixed in next version as well
Very difficult to abstract from your code for testability and for use in multi tiered environments, but it can be done. This can also be classified as the POCO problem that also has been resolved.
There are more, but these are my top ones.
Overall I would use it again, but if you are starting from scratch please save yourself some pain and wait for the latest version or start using the beta if you can.
You might find the walkthroughs for Entity Framework 4.0 useful. All of the new features discussed are annoying emissions from the currently released version for someone.
I found the new TDD/testability features and T4 code generation features especially interesting.
About EF1:
Generated SQL is horrible. It multiples joins, it is 10x bigger than it could. I had a simple query, but with a lot of joins and generating this query by EF (not executing) was slowing down significantly my application. No, I couldn't use precompiled query. I used view to cope with it. SQL Profiler was helpful.
Primary keys in views are not recognized properly. You have to change edmx file by hand when you import view or doing schema refresh.
You can design entities from database in graphical manner, update model from database, but it doesn't always work good, specially when you change field types or foreign keys.
You can't update one table in model, always have to update whole model from db.
You can't define base class for your entities, it is already defined (EntityObject). You can use interfaces, because classes are defined as partial.
No POCO, entity classes are strongly connected to framework.
You can set foreign key by EntityReference.EntityKey, but when you have EntityCollection, prepare for round trip to db. Or am I missing something?
I am finding the POCO objects and model-first design in the EF4 beta very sexy.
I am using Entity Framework to layer on my SQL Server 2008 database. The EF is present in my web service and the webservice is invoked by a Silverlight client.
I am seeing a serious performance issue in terms of the duration taken by a query to execute in the EF. This wouldn't happen in the consecutive calls.
A little bit of googling revealed that, it's caused per app domain to construct the in-memory model of the db objects. I found this Microsoft link explaining pre-generation of views for performance improvement. Even after implementing the steps, the performance actually degraded instead of improving. I am curious, if anyone has tried this approach successfully and if there are any other avenues for improving performance.
I am using .NET 3.5.
A couple areas to look at for EF performance
Do as much of the processing before calling things like tolist(). ToList will bring everything in the set into memory. By default, EF will keep building the expression tree and only actually process it when you need the data in memory. That first query will be against the database, but afterwards the processing will be in memory. When working with large data, you definitely want as much of the heavy lifting done by the database as possible.
EF 1 only has the option to pull the entire row back. Therefore if you have a column that is a large string or binary blob, it is going to be pulled down and into memory whether you need it or not. You can create a projection that doesn't include this column, but then you don't get the benefits of having it be an entity.
You can look at the sql generated by EF using the suggestion in this post
How do I view the SQL generated by the Entity Framework?
The same laws of physics apply for EF queries as they do for ordinary SQL. Check your database tables and make sure that you have indexes on primary and foreign keys, that your database is properly normalized, and so forth. If performance is degrading after Microsoft's suggestions, then that's my guess as to the problem area.
Are you hosting the webservice in IIS? Is it running on the same site as the Silverlight App? What about the database itself? Is it running on a dedicated machine? Are there other apps hitting it? The first call to a dormant database is painful (I've had situations where it would actually time out in my environment.)
There are a number of factors to take into consideration here. But it comes down to more than just EF's overhead.
edit I didn't fully qualify but the process of opening the first connection to SQL Server is slow regardless of your data access solution.
Use SQL Profiler to check how many queries executed to retrieve your data.If it's large number use Include() method of ObjectQuery to retrieve child objects with parent in one query.