How do you seed data with Entity Framework Database First approach? - entity-framework

I see many examples of seeding with Code First, but I'm not sure I understand what the idiomatic way of seeding the database when using EF Database First.

Best practice is very situation dependent. Then there is the DEV versus PROD environments.
Auto seed when using Drop and recreate on model change during DEV so you have test data makes the most sense. This is when it used most.
Of cause you can a have a test method that you trigger manually. I personally find the idea an automatically triggered seed method not that exciting and more for DEV prototyping when the DB structure is volatile. When using migrations, you tend to keep your hard earned test data. Some use Seeding during initial installation in PROD. Others will have a specific load routines triggered during the installation/commissioning process. I like to use custom load routines instead.
EDIT: A CODE FIRST SAMPLE. With DB First you just write to the Db normally.
// select the appropriate initializer for your situation eg
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDbContext, MyMigrationConfiguration>());
Context.Database.Initialize(true); // yes now please
//...
public class MyMigrationConfiguration<TContext> : DbMigrationsConfiguration<TContext>
where TContext : DbContext{
public MyMigrationConfiguration() {
AutomaticMigrationsEnabled = true; //fyi options
AutomaticMigrationDataLossAllowed = true; //fyi options
}
public override void Seed(TContext context)
{
base.Seed(context);
// SEED AWAY..... you have the context
}
}

Related

Bulk Insert Optimization in .NET / EF Core

I have some .NET Core code that does some bulk loading of the DB with random sample data.
I'm getting 20 inserts/second on localhost, and looking to improve my performance. I'm doing the basic stuff like calling _dbContext.SaveChanges() only once, etc.
A number of posts like this indicate gains can be had by manipulating properties on the DbContext's Configuration, such as Configuration.AutoDetectChangesEnabled and Configuration.ValidateOnSaveEnabled.
My .NET Core MVC app's DbContext is a subclass of IdentityDbContext, which does not expose the Configuration.
Not sure what approach I should be using - can I / should I be messing with those configuration properties of a IdentityDbContext subclass?
Or, should I use a separate DbContext for this? (Some early research indicated the typical pattern is a single DbContext for a webapp).
There is no need for creating separated DbContext class and you can turn change tracking off:
context.ChangeTracker.AutoDetectChangesEnabled = false;
or you can turn it off globaly:
public class MyContext : IdentityDbContext
{
public MyContext()
{
ChangeTracker.AutoDetectChangesEnabled = false;
}
}

Entity Framework 5 : Using Lazy Loading or Eager Loading

I'm sorry if my question is normal. But I meet this problem when I design my ASP.NET MVC 4.0 Application using Entity Framework 5.
If I choose Eager Loading, I just simplify using :
public Problem getProblemById(int id) {
using(DBEntity ctx = new DBEntity ())
{
return (Problem) ctx.Posts.Find(id);
}
}
But if I use Eager Loading, I will meet problem: when I want to navigate through all its attributes such as comments (of problem), User (of Problem) ... I must manually use Include to include those properties. and At sometimes, If I don't use those properties, I will lost performance, and maybe I lost the strength of Entity Framework.
If I use Lazy Loading. There are two ways to use DBContext object. First way is using DBContext object locally :
public Problem getProblemById(int id) {
DBEntity ctx = new DBEntity ();
return (Problem) ctx.Posts.Find(id);
}
Using this, I think will meet memory leak, because ctx will never dispose again.
Second way is make DBContext object static and use it globally :
static DBEntity ctx = new DBEntity ();
public Problem getProblemById(int id) {
return (Problem) ctx.Posts.Find(id);
}
I read some blog, they say that, if I use this way, I must control concurrency access (because multi request sends to server) by myself, OMG. For example this link :
Entity Framework DBContext Usage
So, how can design my app, please help me figure out.
Thanks :)
Don't use a static DBContext object. See c# working with Entity Framework in a multi threaded server
A simple rule for ASP.Net MVC: use a DBContext instance per user request.
As for using lazy loading or not, I would say it depends, but personally I would deactivate lazy-loading. IMO it's a broken feature because there are fundamental issues with it:
just too hard to handle exceptions, because a SQL request can fail at any place in your code (not just in the DAL because one developer can access to a navigation property in any piece of code)
poor performances if not well used
too easy to write broken code that produces thousands of SQL requests

Possible to have DbContext Ignore Migration/Version data in Database?

I have an application that uses two separate models stored in a single database. The first model is set up with migrations and is the one that has created the migrations data in the database. The second is a very simple model that needs no model validation at all - the tables it uses exist and are of the proper structure. The second Context works fine in a separate database with the same table structure.
The problem is it fails when running in the same database with the first model since it does provide some sort of model validation. It complains that the context has changed since the last update, but of course the the migrations data does not contain anything about the second context's tables.
Is it possible to turn off the meta data validation for the context, and just let the second context work against the tables as is, since I know that works?
in the context constructor but that has no effect.
The solution is to use implement a "do nothing" database initializer that basically does nothing.
public class QueueMessageManagerContextInitializer : IDatabaseInitializer<QueueMessageManagerContext>
{
protected void Seed(QueueMessageManagerContext context)
{
}
public void InitializeDatabase(QueueMessageManagerContext context)
{
// do nothing
Seed(context);
}
}
To use in one time startup code then:
[ClassInitialize()]
public static void MyClassInitialize(TestContext testContext)
{
//Database.SetInitializer<QueueMessageManagerContext>(new DropCreateDatabaseIfModelChanges<QueueMessageManagerContext>());
Database.SetInitializer<QueueMessageManagerContext>(new QueueMessageManagerContextInitializer());
}
Simple but non-obvious solution.
Edit:
Even simpler solution: Just pass NULL to the SetInitializer() method:
Database.SetInitializer<QueueMessageManagerContext>(null);

EF: In search of a design strategy for DatabaseFirst DbContext of a Modular Application

I'm looking for suggestions on how to approach using an ORM (in this case, EF5) in the design of modular Non-Monolithic applications, with a Core part and 3rd party Modules, where the Core has no direct Reference to the 3rd party Modules, and Modules only have a reference to Core/Common tables and classes.
For arguments sake, a close enough analogy would be DNN.
CodeFirst:
With CodeFirst, the approach I used was to build up the model of the Db was via reflection: in the Core's DbContext's DbInitialation phase, I used Reflection to find any class in any dll (eg Core or various Modules) decorated with IDbInitializer (a custom contract containing an Execute() method) to define just the dll's structure. Each dll added to the DbModel what it knew about itself.
Any subsequent Seeding was also handled in the same wa (searching for a specific IDbSeeder contract, and executing it).
Pro:
* the approach works for now.
* The same core DbContext can be used across all respositories, as long as each repo uses dbContext.GetSet(), rather than expecting it to be a property of the dbContext. No biggie.
Cons:
* it only works at startup (ie, adding new modules would require an AppPool refresh).
* CodeFirst is great for a POC. But in EF5, it's not mature enough for Enterprise work yet (and I can't wait for EF6 for StoredProcs and other features to be added).
* My DBA hates CodeFirst, at least for the Core, wanting to optimize that part with Stored Procs as much as as possible...We're a team, so I have to try to find a way to please him, if I can find a way...
Database-first:
The DbModel phase appears to be happening prior to the DbContext's constructor (reading from embedded *.edmx resource file). DbInitialization is never invoked (as model is deemed complete), so I can't add more tables than what the Core knows about.
If I can't add elements to the Model, dynamically, as one can with CodeFirst, it means that
* either the Core DbContext's Model has to have knowledge of every table in the Db -- Core AND every 3rd party module. Making the application Monolithic and highly coupled, defeating the very thing I am trying to achieve.
* Or each 3rd party has to create their own DbContext, importing Core tables, leading to
* versioning issues (module not updating their *.edmx's when Core's *.edmx is updated, etc.)
* duplication everywhere, in different memory contexts = hard to track down concurrency issues.
At this point, it seems to me that the CodeFirst approach is the only way that Modular software can be achieved with EF. But hopefully someone else know's how to make DatabaseFirst shine -- is there any way of 'appending' DbSet's to the model created from the embedded *.edmx file?
Or any other ideas?
I would consider using a sort of plugin architecture, since that's your overall design for the application itself.
You can accomplish the basics of this by doing something like the following (note that this example uses StructureMap - here is a link to the StructureMap Documentation):
Create an interface from which your DbContext objects can derive.
public interface IPluginContext {
IDictionary<String, DbSet> DataSets { get; }
}
In your Dependency Injection set-up (using StructureMap) - do something like the following:
Scan(s => {
s.AssembliesFromApplicationBaseDirectory();
s.AddAllTypesOf<IPluginContext>();
s.WithDefaultConventions();
});
For<IEnumerable<IPluginContext>>().Use(x =>
x.GetAllInstances<IPluginContext>()
);
For each of your plugins, either alter the {plugin}.Context.tt file - or add a partial class file which causes the DbContext being generated to derive from IPluginContext.
public partial class FooContext : IPluginContext { }
Alter the {plugin}.Context.tt file for each plugin to expose something like:
public IDictionary<String, DbSet> DataSets {
get {
// Here is where you would have the .tt file output a reference
// to each property, keyed on its property name as the Key -
// in the form of an IDictionary.
}
}
You can now do something like the following:
// This could be inside a service class, your main Data Context, or wherever
// else it becomes convenient to call.
public DbSet DataSet(String name) {
var plugins = ObjectFactory.GetInstance<IEnumerable<IPluginContext>>();
var dataSet = plugins.FirstOrDefault(p =>
p.DataSets.Any(ds => ds.Key.Equals(name))
);
return dataSet;
}
Forgive me if the syntax isn't perfect - I'm doing this within the post, not within the compiler.
The end result gives you the flexibility to do something like:
// Inside an MVC controller...
public JsonResult GetPluginByTypeName(String typeName) {
var dataSet = container.DataSet(typeName);
if (dataSet != null) {
return Json(dataSet.Select());
} else {
return Json("Unable to locate that object type.");
}
}
Clearly, in the long-run - you would want the control to be inverted, where the plugin is the one actually tying into the architecture, rather than the server expecting a type. You can accomplish the same kind of thing using this sort of lazy-loading, however - where the main application exposes an endpoint that all of the Plugins tie to.
That would be something like:
public interface IPlugin : IDisposable {
void EnsureDatabase();
void Initialize();
}
You now can expose this interface to any application developers who are going to create plugins for your architecture (DNN style) - and your StructureMap configuration works something like:
Scan(s => {
s.AssembliesFromApplicationBaseDirectory(); // Upload all plugin DLLs here
// NOTE: Remember that this gives people access to your system!!!
// Given what you are developing, though, I am assuming you
// already get that.
s.AddAllTypesOf<IPlugin>();
s.WithDefaultConventions();
});
For<IEnumerable<IPlugin>>().Use(x => x.GetAllInstances<IPlugin>());
Now, when you initialize your application, you can do something like:
// Global.asax
public static IEnumerable<IPlugin> plugins =
ObjectFactory.GetInstance<IEnumerable<IPlugin>>();
public void Application_Start() {
foreach(IPlugin plugin in plugins) {
plugin.EnsureDatabase();
plugin.Initialize();
}
}
Each of your IPlugin objects can now contain its own database context, manage the process of installing (if necessary) its own database instance / tables, and dispose of itself gracefully.
Clearly this isn't a complete solution - but I hope it starts you off in a useful direction. :) If I can help clarify anything herein, please let me know.
While it's a CodeFirst approach, and not the cleanest solution, what about forcing initialization to run even after start up, as in the answer posted here: Forcing code-first to always initialize a non-existent database? (I know precisely nothing about CodeFirst, but seeing as this is a month old with no posts it's worth a shot)

How should I separate integration tests for an EF code first DAL and pure unit tests of the DAL clients?

Having seen some strong advice against testing EF against mocks, especially Code First, I have decided to go with integration testing against a SqlCe database dedicated to testing, and then use pure unit tests further downstream from the unit of work and repositories provided by DbContext and DbSet.
I am just unclear where to draw the line and what to test where. I know I can mock the DAL in my service layer when I am confident the DAL specific integration tests cover its insides, but what do I test in the DAL? There doesn't seem to be much point testing to see if I can save and read an object, because EF is external and already tested.
You will test your mapping and queries in DAL by using integration tests. Example:
public class Service {
private readonly IDAL _dal;
public Service(IDAL dal) {
// Not null validation here
_dal = dal;
}
public void DoSomething() {
SomeData data = FindSomeData();
// Do some logic
_dal.Commit();
}
protected virtual SomeData FindSomeData() {
return _dal.SomeData.Where(...).FirstOrDefault();
}
}
This is very simplified example showing:
Service dependent on DAL. DAL interface is passed through constructor injection.
The Service contains public DoSomething method you want to test to know if the logic is executed correctly. But this method is also dependent on DB query and DB persistence (Commit).
The query is part of your logic but executing such query is separate concern so it is handled by its own method. In more complex situation this method can be in other class injected to the Service class (repository). The key criteria for these query methods are:
They don't return IQueryable
They don't accept Expression<> as parameters
How to unit test DoSomething method:
In this simple example your test class will derive from Service class and override FindSomeData to return test data. In case of injection you would instead define fake for injected class.
You will also mock IDAL and you can verify that Commit was called
What integration test you should use:
You should create test for FindSomeData querying the real database
In general you should also have integration test for Commit but it is more difficult to achieve because the example has commit called directly from DoSomething. You don't want to test that method again and in the same time Commit method has too much generic cases because it simply flushes all changes from current context to database. I usually have separate tests for inserting, updating and deleting every entity type. When the DoSomething method does some complex modification you can split the method into two methods one handled by unit test for a real logic and second covered by integration tests for different persistence scenarios which can be produced by your logic.
Entity Framework is tested, but your DAL, especially mapping, is not. I prefer having integration tests to show me that at the very least my mapping is right, and better yet, that I can successfully perform all CRUD operations against my database.
What we usually test DB-wise, is if the complex object graphs can be properly inserted, updated, deleted; basically testing the more complex mappings.
In my opinion there's not really much point in testing if an object with 3 primitive value properties can be inserted and whatnot, because then you'd never see the end of it.
We kind of favor being optimistic (that the simple stuff will just work), we test the more complex associations, and if we encounter an error in our mapping (e.g. an object that should be deleted but isn't) we write an extra test for that.
It's usually not wise to test absolutely everything from a business perspective; you should focus on the high-risk/high-damage stuff first and then work your way down the severity ladder until you think it's not worth it anymore.
1) Have a set of integration tests which test your mappings
2) Make your DAL very light weight but with sufficent power to construct querys, something like:
public interface IDb
{
IQueryable<T>Query<T>();
... (save, delete, get-by-id methods)...
}
3) Write objects which encapsulate the logic behind constructing the query against the DAL
public class MuppetSearch
{
public MuppetColor? Color { get; set;}
public string Name{ get; set; }
public IQueryable<Muppet> ConstructQuery(IDb db)
{
var query = db.Query<Muppet>();
if(Color.HasValue)
{
query = query.Where(m=>m.Value == Color.Value);
}
if(!String.IsNullOrEmpty(Name))
{
query = query.Where(m=>m.Name.Contains(Name));
}
return query;
}
}
4) Test those, mocking all the data you need should be pretty trivial
5) In your service use the search classes to do your query construction