Prevent Entity Framework 5 from querying Information_Schema_Tables - c#

With EF 4.1, you used to remove the IncludeMetadataConvention in order to prevent EF from querying for database metadata on every query.
In EF 5, I get a warning about IncludeMetadataConvention being obsolete, and in LinqPad, I can see that EF is now querying for migration history on every use. I'm working on a database first project (but using POCO's and DbContext). I don't want the overhead of these extra queries. How do I turn them off?
Update
I found that I can disable this on a per-dbContext basis by calling
System.Data.Entity.Database.SetInitializer<theDbContext>(null);
However, I would like to be able to disable initialization globally (Imagine a large app, and we want to ensure that we are not running these queries (and definitely not trying to create a database) when it is deployed for production.

If you need to do it for every context type in your large application you can create some code which will go through all of your assemblies, find all types derived from DbContext and invoke that call through reflection for every found type.
Btw. since EF 4.3 you can also change initializer from configuration but it is still per context basis because people usually don't have more than one.

Why not put the code in the constructor of your DbContext classes?
I do this as well as set a parameter to disable AutoDetectChangesEnabled, LazyLoading & Proxy CreationEnabled.

Related

How to check automatically that I didn't forget to add ef core code first migration

We are using Entity Framework Core 2.2 with code first. Sometimes I change one of the entities, but forget to create a new migration, or I create a migration but only in one context (we have for different db engines). I want to check it automatically (ideally as NUnit test) so it runs in our CI server for every commit.
Manually I would try to create a new migration and check that created Up() and Down() methods are empty. It there any way to do it as a NUnit test?
Where is difficulty in creating a test that :
Creates a new DB
Applies all current migrations to create a schema
Tries to use all the entities. It can be as simple as adding an entity, querying that entity and deep-comparing they are the same.
Drops the DB
If the schema doesn't have a migration for new entity or change in entity, you are sure to get and SQL error out of this.
Sure, every time you create a new entity, you would need to add a new test. But that should be already happening if you are using TDD.
And speed shouldn't be a problem either, as creating and dropping a DB shouldn't take more than few seconds and there won't be many of these kind of tests. And they can be parallelized.
If you want to get fancy and don't want to write test for each entity, it could be possible to do something like this :
Use reflection to get all entity types supported by a Context.
Use auto data generator like Bogus or AutoFixture to fill the entities with data.
Round-trip the entities through DB.
Compare the original with retrieved using deep-comparer like Compare-Net-Objects.
The usefulness of such automated approach would depend on complexity of your data model. Would just work for simple model. But would require lots of tweaking and overrides if the model is complex.

How to update / synchronize DbContext after external changes to the database

I am using Entity Framework 6 where, for performance reasons, I load my entities into my DbContext up front and then use them locally. Up to now, all changes to the database have gone through the DbContext so my local entities and the database have been in sync. However, I now have to call a Stored Procedure on the database, which has the side effects of making changes to tables (outside of the DbContext) that need to be reflected in my entities. By changes, I mean it is adding new records and deleting / updating existing records.
I do not want to dispose of my DbContext and create a new one, as some of the entity instances are wrapped within ViewModel classes. So, deleting the DbContext in this way would lead to major problems in the UI.
It is my understanding that simply calling Load() on all my DbSets of the DbContext will just replace the existing instances. So, any objects using the old entities instances won't work.
So, I thought I could use the Reload method like:
context.Entry(entity).Reload();
which would update my local entities, but I can only do this for the entities that the DbContext already knows about. It doesn't cover any NEW entities or DELETED entities that were created / deleted as a result of the Stored Procedure executing.
So, I am looking for a way to:
Load, from the database, entities that are NEW to my DbContext
Reload existing entities in my DbContext
Remove any deleted entities from my DbContext
Here is the official documentation for Entity Framework.
Starting from the analysis of your database situation, it suggests smart and quick ways to obtain what you want, detailing when necessary data-read strategies (like eager or lazy loading) or providing tutorials to correctly use code generation and the Wizard GUI.
http://www.entityframeworktutorial.net/choosing-development-approach-with-entity-framework.aspx
Here some more detailed info and tutorial on data-read strategies:
https://www.c-sharpcorner.com/article/eager-loading-lazy-loading-and-explicit-loading-in-entity-framework/
As I already told you in comments, I would suggest a database-first approach and with lazy loading to avoid uncontrolled data behaviours (or reloading the whole db when running a stored procedure).
Talking about the SP, it can simply be mapped through the Wizard that comes with Entity Framework and wrapped by a method.
Hope you will find these resources helpful!
In general EntityFramework can not aware on change in database and update dbcontext .there is no optimized or EntityFramework built-in solution for it.
I think you can use CDC in SqlServer, push change to your application and update your dbcontext. But it not acceptable solution for all business and senario

Entity Framework 5 log database changes at runtime

In an ASP.NET 4.5 C# Entity Framework 5 Code First project I'd like to log the changes being made in the database at runtime (the logging has to be done in the asp.net app, not at the database). Previously, the SQL statements were built by the code, and those statements were simply logged. Now with EF, the object is retrieved via linq to entities, modified and
db.SaveChanges();
is being called. My first idea was to retrieve the actual SQL statements that EF sends to the DB -- this seems to be rather complex, however. I've found many "solutions" for displaying the SQL during debugging, but no simple way for the code to retrieve it at runtime.
So I'm looking for any solution that can log the changes being made (either the SQL being sent to the DB [preferred], or some other form of textual representation of the changes made to the object), and that doesn't require the inclusion of a number of complex debug libraries.
You should try FrameLog
https://bitbucket.org/MartinEden/framelog/wiki/Home
It is not clearly stated but it supports Entity Framework 5
I haven't tested this on EF 4.5 so it may need to be tweaked a bit, but I find for debugging purposes the extension method written at the bottom of this post:
http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/2a50ffd2-ed73-411d-82bc-c9c564623cb4/
Gives me the correct output of my entities.SaveChanges() call. It doesn't require any external libraries and since it's written as an extension method it won't clog up your code.

Modifying an ORM model at run time

there has been quite bit of discussion on this topic ( Modifying an Entity Framework Model at Run-Time), but so far I haven't been able to find a nice solution to the problem. We currently have a model built with EF 4.0 and need to allow customers to add custom fields to various tables. We have currently solved the problem with a few generic tables that describe the new properties, but we're finding that the solution is not performing well.
Does anyone know of a good way to dynamically add columns to the database and also update the ORM to reflect that at run-time?
There is no good, nice or manageable way to update EF at runtime to reflect changes in the database. If you really have a database which must change at runtime EF is not good tool for you. EF is strongly typed - every change to database must be reflected not only in mapping but also in entity classes used for loading and persisting data.
Changing entity classes at runtime always goes to area of emitting IL code at runtime. If you pass the process of creating dynamic assembly with dynamic module and dynamic entity types you will face a lot of new challenges:
You will not change your existing types - you will generate a new type every time the user adds or removes some property.
A new type generation brings a new performance cost for rebuilding context's metadata workspace. You must also make sure that this is correctly synchronized if you use it on a server. Another problem is that all existing instances of the old type (before adding or removing property) are now unknown to new instances of EF context and cannot be persisted. If you want to persist them as well you need EF context instances with old metadata workspace as well.
A lot of your code will probably use dynamic instead of real type = no compile time checking. Inheritance and interfaces will not be useful when interacting directly with EF because inheritance must be mapped (you don't want it) and interfaces are not accepted by EF.
The new type is unknown at design time - you cannot use it for design time code and compilation.
EF doesn't like dynamic or ExpandoObject because it uses reflection for mapping -> at runtime your dynamic instance must be correct type otherwise reflection will not work.
How to write queries for dynamic type? The query always starts at generic instance of DbSet or ObjectSet created for concrete type - you must be able to make those instances dynamically as well. Generic argument must be a type mapped to current context - dynamic will not help in this case because it is not a mapped type.
.NET has a nice behavior for this case. It cannot unload assembly. So every time you generate a new type you will have an old time loaded as well.
Do you still want to change EF at runtime? Your current approach is correct one. Simply tune it for better performance but beware that these requirements always come with performance costs - especially with EF.
Alternatively use the last approach mentioned with linked table - fixed number of predefined custom fields directly in the main entity.

EF Code First - SqlServerCE Trigger

i use the entity framework code first for my application and i need a trigger.
My Application should support different database engines like
Sql Server
SqlServerCE
SqlExpress
Trigger, Stored procs are not supported in SqlServerCE, what would you do to get this
functionality?
I could do something after "SaveChanges" or something, what is a good way ?
Yes you can do something inside SaveChanges (by overriding) or after SaveChanges and call SaveChanges again to persist new data but it is not exactly the same as trigger. Simply if your requirement is to use trigger for some functionality SqlServerCE is not a choice for you. If you rewrite the trigger logic to your application you should have two versions anyway - one for big SQL using triggers and one for SQL CE not using triggers.
Code first, although it allows you to send in some raw queries and hence perform your own native database/server manipulations, basically is designed only for building a model and querying upon that model.
Now as for your question: You can directly build 'stored procedure alternatives' by adding methods to your DbContext (or extension methods for seperation of concerns).
Triggers are a little more complex. You can override the SaveChanges method in which you can basically track each change made either before it got persisted back to the database- or after.
Both problems however can also be solved by introducing a repository. See: http://huyrua.wordpress.com/2011/04/13/entity-framework-4-poco-repository-and-specification-pattern-upgraded-to-ef-4-1 This allows you to launch a script (trigger) when adding, updating or removing a certain entity

Categories

Resources