In my application I have 2 contexts targeting the same SQL database. One context is for my AspNet Identity tables and the other one is for the rest of the application. What I am trying to do is make my 'User' table (which is for the IdentityUser class in my IdentityDbContext) available in my ApplicationContext. I am using Code First Migrations and do not want the ApplicationContext to attempt to create (or modify) that table - I just want it to 'know' about it and be able to query and join it to other tables but want it ignored by the MigrateDatabaseToLatestVersion<ApplicationContext, Configuration>() initializer or when issuing update-database from the Package Manager console.
I have found a few similar questions but no suitable answers.
In this cases I think, you have to create a separate DbContext That contains all DbSets from all your DbContexts and use this master DbContext for migrations purpose.
If you want some entities be read-only in some your contexts(User in your case) you can define entitiy's DbSet as following
public ApplicationContext:DbContext
{
...
public DbSet<User> Users { get; private set; }
}
private setter for a DbSet cause it can set by Entity Framework, but not by users.
Related
I have an existing application that is built on Entity Framework Core 2.2.x. It is using modelBuilder.ApplyConfiguration() to associate entities with the data model dynamically. This works for all of the current entities and even my new AuditLog entity as far as the rest of the application is concerned.
However, when I configure Audit.NET's entity framework core provider to log into AuditLog, the data provider cannot write to the database:
The entity type 'AuditLog' was not found. Ensure that the entity type has been added to the model.
I have scoured the internet for solutions to that error, and found that adding this line to my code will cause Audit.NET to find my AuditLog:
modelBuilder.Entity<AuditLog>().ToTable("AuditLog", "Audit");
My code:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
Type[] maps = EntityFrameworkReflectionMapping.Get(EntityTypeConfiguration(), BoundAssemblies);
foreach (object instance in maps.Select(Activator.CreateInstance))
modelBuilder.ApplyConfiguration((dynamic)instance);
modelBuilder.Entity<AuditLog>().ToTable("AuditLog", "Audit");
base.OnModelCreating(modelBuilder);
}
Why do I need to add the entity explicitly, when the rest of the system works as-is?
Additionally, the changes are being detected by Audit.NET through entities which are not explicitly added. So the problem seems to be with Audit.NET's entity framework data provider, or how I'm using it.
I would expect that the data provider would respect the modelBuilder.ApplyConfiguration() approach to associating entities.
There are many things that could be causing the exception, but looks like EF is not being able to detect the entity-table relation for your AuditLog.
Look for a wrong connection string, maybe your AuditLog being defined on a different assembly than other entities.
Also try adding the AuditLog entity class within a db set as a property on your DbContext, for example:
public class MyContext : AuditDbContext
{
//...
public DbSet<ModelName> ModelName { get; set; }
}
Can i use Entities that are already a part of my project as Entity Framework Entities.
My project Follows Domain Driven Design that do contain all entities that represents my database tables.
I do not want Entity Framework to generate new entities from my existing database, rather i want it to use existing entities in my project.
when ever i use my existing Entities in DB Context Class like this:
public DbSet<SomeOtherProjectInSoulution.ChequeBookRequestAuditLog> ChequeBookRequestAuditLogs { get; set; }
public DbSet<SomeOtherProjectInSoulution.OfflinePayOrderRequestAuditLogEntity> OfflinePayOrderRequestAuditLogEntities { get; set; }
public DbSet<SomeOtherProjectInSoulution.FundsTransferAuditLogEntity> FundsTransferAuditLogEntities { get; set; }
it Gives me the following Error:
The entity type FundsTransferAuditLogEntity is not part of the model for the current
context.
Even though these entities are EXACT Replica of entities that were created by Entity Framework but i deleted them
DB Context:
public partial class PRISMEntitiesTest : DbContext
{
public PRISMEntitiesTest()
: base("name=PRISMEntitiesTest")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public DbSet<Application.Domain.AuditLog.ChequeBookRequestAuditLog> ChequeBookRequestAuditLogs { get; set; }
public DbSet<Application.Domain.AuditLog.OfflinePayOrderRequestAuditLogEntity> OfflinePayOrderRequestAuditLogEntities { get; set; }
public DbSet<Application.Domain.AuditLog.FundsTransferAuditLogEntity> FundsTransferAuditLogEntities { get; set; }
}
The problem is that, when you make a change in the model, the entity (the class) changes, and the EF model doesn't match with the DB. The first time a DbContext is initialized in an application it checks if the EF model matches the DB. If you update the model, and don't update the DB you'll get an exception.
One alternative is marianoc84 answer: drop and create the DB on all iterations, but I must propose a cleaner solution:
forget the model that you have in the designer view
use pure EF Code First, i.e. define the model using code, not a diagram
use Migrations
You can do the task 1 by deleting it. Yep, delete the model. You're using DDD, you don't need that
For the step 2, you can use something like "EF Reverse POCO Code First Generator". This will allow you to create one or several Code First models from your DB (i.e. create pure POCO classes, and the Code First configuration for them, like column types and sizes, keys, relations...). When you get used to this way of working, you'll see that it matches DDD in a better way, because, instead of modifying a diagram, you'll directly modify an entity (class) and can move that changes to the DB (that's the step 3)
Setp 3: If you use marianoc84 solution, and have only one DbContext, you don't need to take this step. If you have several context,or don't want to drop and create the DB whenever you start your app, then you can use Migrations. With Migrations you can evolve the Code First model and apply the changes to the DB in a non-destructive way. Basically you make to enable migrations and create an "Initial Migration" in the initial moment when the DbContext and the DB schemas match in their original state. You'll see a file created in a "Migrations" folder in your project. From this point on, you can change the classes in your DbContext, and create new Migrations. Each migration have "instructions" on how to modify the DB schema from the previous migration to the recently created (Up) and vice versa (Down), and you have to give it a name. When you want to update the database, you simply have to do run an Update-Database command, which, by default, will update your DB to match the last migration.
In fact Migrations are much more powerful: they allow to move up and donw from migration to migration, apply the changes directly in the DB, be suctomized, generate a SQL Script to update the DB... Google for EF Migrations and you'll find a lot of examples on how you use it. But perhaps this is the best information available.
NOTE: the new EF release which is being developed, and will be probably named "Entity Framework 7", won't have the option to define the DB as a diagram: it will be compulsory to use Code First, and there are good reasons for it. You can get plenty of info about this in the ADO.NET blog.
Try adding this constructor, to your class:
public PRISMEntitiesTest(string nameOrConnectionString)
: this(nameOrConnectionString, new DropCreateDatabaseIfModelChanges<PRISMEntitiesTest>()) { }
DropCreateDatabaseIfModelChanges is an implementation of IDatabaseInitializer that will DELETE, recreate, and optionally re-seed the database only if the model has changed since the database was created.
This is usefull in coding phase, since you can ignore schema issues.
I am using VS 2010 and Entity Framework code first (version 6). I have two entities each in its own context and I want to create a one-to-many relationship between them.
Context 1 has the following entity:
public class MyTrust
{
public int MyTrustID { get; set; }
public string MyTrustName { get; set; }
}
and Context 2 has the following entity:
public class MyLocation
{
public int MyLocationID { get; set; }
public int MyTrustID { get; set; }
public virtual MyTrust MyTrust { get; set; }
}
with the following Fluent API
modelBuilder.Entity<MyLocation>()
.HasRequired(m => m.MyTrust);
The migration file for Context 2 contains the correct keys but also creates a new table for MyTrust which already exists in the other context.
I know that I can edit the migration file but that is not a solution.
My question is, how to I stop the creation of the second MyTrust table.
UPDATE
There was a major flaw above in that I pasted the wrong code into Context 2. Now corrected. Apologies.
You are working with so-called bounded contexts. The benefit of such contexts and how to work with them is explained in this blog by Julie Lerman.
The problem you experience, none of the contexts can be used in migrations, is addressed in this part:
If you’re doing new development and you want to let Code First create or migrate your database based on your classes, you’ll need to create an “uber-model” using a DbContext that includes all of the classes and relationships needed to build a complete model that represents the database.
Note that you can share the MyTrust type between all contexts, if you observe these rules (from Lerman & Miller's book DbContext, p 233):
An entity can only be attached to one context at a time. This architecture works
best with short-lived contexts where the instance to be shared will be completely
disassociated from one context before it is attached to another.
Entities that are attached to different contexts cannot be attached to one another.
UPDATE
In EF6 you can use multiple contexts for one migration path. See this walkthrough.
I'm looking to implement entity framework version 4.3.1 in my existing project which don't follow this EF.The database is already developed and is currently used applying ado.net.In this case how do I start with to work on EF, is it Database First,Code first.
Even when a database already exists I still use the Code First approach, mapping the tables using annotations, because the domain is way more organized than on the EDMX file. If there are many tables the visual EDMX can become really useless since the design will be overcrowded with data and connections all over the place.
In two steps you can begin with this approach:
1) Create a domain model class, Customer for example, and map it to your table using data annotations:
[Table("tbl_cust")]
public class Customer
{
[Key]
[Column("cust_id")]
public int CustomerId { get; set; }
[Column("cust_name")]
public string Name { get; set; }
// Add other properties below
}
2) Create a context class deriving from DbContext and set DbSet<T> properties for each model, we have only one in our case so:
public class MyApplicationContext: DbContext
{
public MyApplicationContext() : base("name=ConnectionStringName") { }
public DbSet<Customer> Customers { get; set; }
}
Now anywhere in your code can instantiate the derived DbContext class and make queries using Linq:
var _db = new MyApplicationContext();
var customer = _db.Customers.Where(c => c.CustomerId == 37).FirstOrDefault();
Don't forget to add a reference to EntityFramework assembly using NuGet.
Good Luck.
Since your database already exists the obvious choice is Database first. If the database is designed with common sense it (mostly) works great.
I think the question is if you want to use the EF Designer to visualize your database or not. Since you are looking at EF 4.3.1 (in fact you should be looking at EF5 not 4.3.1 - EF5 is the latest version) I assume you don't care about the designer. In this case you could use EF Power Tools to reverse engineer your database. This will create a set of classes that will match your database. Note that since the database has already been created EF will not be able to detect changes in your classes (as opposed to databases created by Code First when additional information is stored in the database and EF is able to tell whether the model has changed). Make sure to read this blog post - it contains a lot of details you may find helpful to make the decision.
If you care about being able to see your model in the designer you can just use VS to reverse engineer DB. If you use VS2012 you will by default get EF5 and DBContext. The difference from using Code First will be that instead of building the model EF needs based on your classes the model is saved in the the edmx file that is part of your project (and used to generate code for you)
I have a legacy EF 4 library with a database-first generated ObjectContext with EntityObjects. I'd like to slowly migrate to using DbContext and am in need of some guidence.
One of the overloads for DbContext takes an existing ObjectContext. I thought this would allow me to wrap my existing ObjectContext in a DbContext and expose my existing EntityObjects through IDbSet properties. Unfortunately, when creating the DbContext, the IDbSet properties are not created and instead an exception is thrown with a message of: "Verify that the type was defined as a class, is not primitive, nested or generic, and does not inherit from EntityObject."
Is there no way to use a DbContext with IDbSet exposing an existing ObjectContext and EntityObjects? It seems strange that I can create a DbContext with an ObjectContext, but not expose the entities themselves.
Here's some sample code:
public class MyDbContext : DbContext
{
public MyDbContext(MyObjectContext objectContext, bool dbContextOwnsObjectContext)
: base(objectContext, dbContextOwnsObjectContext)
{
}
public IDbSet<Person> People { get; set; }
}
The exception is caused by the DbContext trying to create the IDbSet. Person is an EntityObject from my existing EDMX.
As you noted, you cannot use the existing entity objects that the edmx created.
Have you considered using the Reverse Engineer Code First power tools?
I've used them in several projects, and its simple as pointing it at your database, it generates the model in the same project, and then removing the edmx file.