Entity Framework - Add Migration Creating For Entities In External Assembly - entity-framework

I've been using Entity Framework Code First migrations for a while now, and like to think I know the fundamentals pretty well. However, yesterday I came across a rather odd issue which I can't seem to find a solution to.
I've added a reference to a DLL (third party - not developed by ourselves) which has some interfaces I need on my entities. The DLL contains a bunch of other things - such as some classes - which we don't need and aren't using.
Now with the reference, and implementing some of the interfaces - when I add a migration using the Add-Migration command, Entity Framework seems to pick up some of the classes in the DLL, and tries to create tables for them in the migration.
For example, I have a 'User' entity in my project. I have added a reference to ThirdParty.dll, which contains an IThirdPartyUser interface. The DLL also contains a UnusedClass, which I am not using - it is not part of my context in any way.
When I create a migration, I get code to create the database tables for UnusedClass. For example:
CreateTable(
"dbo.UnusedClass",
c => new
{
Id = c.Int(nullable: false, identity: true),
RegistrationNumber = c.Int(),
})
Now my theory is that this external assembly (incorrectly) has some dependency on Entity Framework - but I can't figure out why migrations is trying to generate database code for them - especially as they are not part of my context.
Anyone come across this before? I'm about to embark on a trial and error exercise to try and get to the bottom of the issue.

EF should only pick up classes that are in the object graph originating at your DbContext - so, if class A is in your context, and class A has a property of type UnusedClass, EF will try to scaffold it.
You can add the NotMappedAttribute to a property or class to have EF ignore it when generating its mapping.

Related

cant add migration to ef 7

I am still in the process of porting my old MVC project to the latest asp.net 5 MVC and EntityFramework 7. To accomplish this I first reverse engineered an existing database from the old project using the ef commands. That created all of my model classes correctly (or mostly so). I have manually edited the code to get through all of the initial errors. I have that compiling with almost no additional code from the original project. In other words I only have the model classes, and the DbContext class so far in the solution. All of this is in an assembly and I have no migrations at all in the codebase, just the Migrations directory. What I thought would make sense is to add a migration to baseline the database from what was reverse engineered. I should mention that my DbContext inherits from IdentityDbContext
public partial class STOrmContext : IdentityDbContext<ApplicationUser>
{
}
My project is split into two components. All database and models in an assembly, and MVC stuff in a separate project.
when I type
dnx ef command migrations add Initial
I get the following error message
The entity type 'Microsoft.AspNet.Identity.EntityFramework.IdentityUserLogin<string>' requires a key to be defined.
I guess I just don't really understand how to bootstrap a legacy database into EntintyFramework 7. Can someone point me in the right direction.
I found the answer myself.
It turns out it was a couple of things I was not addressing.
When I reverse engineered the old database it created models for the
identity stuff from the legacy application.
I deleted those.
I also needed to call the base OnModelCreating() so that it could configure
Identity stuff.
protected override void OnModelCreating(ModelBuilder modelBuilder) {
base.OnModelCreating(modelBuilder);
}
I guess I should have paid more attention to what was really happening before jumping to a question on StackOverflow

Can I add the PluralizingTableNameConvention to the EF powertools?

I am currently using the Entity Framework Powertools (beta 4) to generate my POCO classes from an existing db, which has upwards of 800 tables.
Whilst this is awesome, and saving me a lot of time, I noticed that the tool is pluralizing my POCO classes, or de-pluralizing them. Some of our tables are pluralized, and others are not, so to keep things simple, I want the POCO's to match the underlying db table names. In my main DbContext, I have the PluralizingTableNameConvention and PluralizingEntitySetNameConvention removed in the OnModelCreating() method call, so the application is fine.
My question is whether this configuration can be re-created in the EF Powertools so that the classes come out correctly, and do not require me retrofitting the class names etc.
It looks like this cant be done, however I have download the EF Powertools code from Codeplex, and built the tools manually. I then created my own implementation of the PluralizationService in which I did not pluralize anything.
Job done.

Get Model schema to programmatically create database using a provider that doesn't support CreateDatabase

I'm using the SQLite provider for Entity Framework 5 but it doesn't support CreateDatabase and thus cannot auto create the database. (Code First)
Is there a way I can obtain the Model schema at runtime so that I can create the SQL "CREATE TABLE" command myself?
If not at runtime, some other way to obtain the schema so I know how to create the table properly?
Thanks!
A) As for obtaining the model schema at runtime part
(all are earlier posts of mine)
See this one How I can read EF DbContext metadata programmatically?
And How check by unit test that properties mark as computed in ORM model?
Also this one for a custom initializer Programmatic data transformation in EF5 Code First migration
Having said that...
The problem I see is where and at what point you actually have the data available.
Actually I'm quite sure you won't be able to do that at any time.
Because to be able to extract that info you need to have a DbContext running - so db has to be constructed etc. etc.
In the initializer maybe - but using different ways to get that info - the above is not available.
B)
The other way would be to go the way of implementing a provider, generator etc. (e.g. this post).
That way you should get all that info just at the right time from the EF/CF itself.
However I haven't played with that much.
For more info you can check the EF source code
This is more of a 'gathered info' so far - in case it helps you get anywhere with it. Not really a solution. I'll add some more tomorrow.
EDIT:
To get the real database metadata, look into the other DataSpace, this should get you to the right place...
(note: things tend to get less exact from here - as obviously there isn't the right official support)
var ssSpaceSet = objectContext.MetadataWorkspace.GetItems<EntityContainer>(DataSpace.SSpace).First()
.BaseEntitySets
.First(meta => meta.ElementType.Name == "YourTableName");
If you look up in debugger, Table property should have the real table name.
However, reflection might be required.
How I can read EF DbContext metadata programmatically?
How check by unit test that properties mark as computed in ORM model?
Programmatic data transformation in EF5 Code First migration
Entity Framework MigrationSqlGenerator for SQLite
http://entityframework.codeplex.com/
Entity Framework - Get Table name from the Entity
ef code first: get entity table name without dataannotations
Get Database Table Name from Entity Framework MetaData
http://www.codeproject.com/Articles/350135/Entity-Framework-Get-mapped-table-name-from-an-ent

Get DbContext for Entities

Okay, I feel a bit foolish for having to ask this but I guess my understanding of the inner workings of Entity Framework is lacking.
I'd like to experiment with work with DbContext. I have an existing ASP.NET MVC application using EF 4.2. I can get my entities using:
var context = new MyEntities();
And this works just fine.
But how the heck to I get the same data represented by a DbContext?
So I guess you are using default code generator provided by EDMX designer - it will use ObjectContext and heavy weight EntityObject based entities.
If you want to use DbContext you must:
Turn off that default code generation - in property window remove Custom Tool for EDMX file
Download and install DbContext T4 generator (you can get it directly from extension manager in Visual Studio)
In EF designer select Add Code Generation Item from context menu in the designer surface (not on entity)
Now EF will add two .tt files to your project - one will be responsible for creating a new class for every entity or complex type defined in your EDMX file and the second will be responsible for creating class derived from DbContext and exposing sets for all your entity types

Table per hierarchy inheritance with POCO entities in Entity Framework 4

Our organization is looking to standardize on Entity Framework once v4 comes out. As a result, I am looking at what it would take to migrate our application that uses NHibernate for persistence to EF4 using POCO support. In a couple of places we use single table inheritance (also known as Table Per Hierarchy). I have been unable to get it to work using the following.
Payment (base class [should be abstract but having trouble there as well])
CreditCardPayment (concrete implementation)
ACHPayment (concrete implementation)
CheckPayment (concrete implementation)
Right now, I am mapping them with only the base class properties. All of these classes are in the same namespace. They have a discrimimator that is called PaymentTypeId in the database, so the Payment mapping has a condition of "When PaymentTypeId = 0". Each of the subclasses have the same condition with different values (i.e. CreditCardPayment = 1, etc.).
When I try to load each a list of all payments using DataContext.Payments.ToList() (DataContext inherits from ObjectContext) I am getting the following exception:
"Object mapping could not be found for Type with identity 'DataLayer.DataModel.CreditCardPayment'."
I can't figure out what this means, as the POCO CreditCardPayment class lives in the same namespace as the POCO Payment class does (in fact in the same file).
What am I missing?
This is complaining not about database mapping, but model to CLR mapping.
The EF can't for some reason find your CreditCardPayment class.
Now one possible reason is that you haven't loaded the metadata for it yet.
For example if you have this:
Assembly 1:
- Payment
Assembly 2 references Assembly 1:
- CreditCardPayment extends Payment
Then when you query the EF doesn't know where CreditCardPayment lives.
The way to get around this is with LoadAssembly i.e:
using (DataContext ctx = new DataContext())
{
ctx.MetadataWorkspace.LoadFromAssembly(typeof(CreditCardPayment).Assembly);
// now do your query.
}
You need to tell to LoadFromAssembly every assembly that isn't directly reference by your DataContext class.
Note: typeof(Payment).Assembly is directly referenced because of the IQueryable<Payment> Payments property.
Hope this helps
Alex
Microsoft.
What I didn't represent before (I didn't think it relevant, but it was). Was that CreditCardPayment inherited from an intermediary class named "CreditPayment" and ACHPayment inherited from CashPayment. CreditCardPayment and CashPayment live in the same namespace and file, but were not represented in the EF mapping. Once I added those within the mapping file, everything worked ok.
So, even thought EF does not ever map to one of those types directly, it seems to need to know about them, because it changes the basetype of the CreditCardPayment classes et al. Thank you for your help on this.