Entity Framework - Inserting entity with multiple models and databases - c#

I have my domain split into multiple Entity Framework models. I have some shared entities that span multiple models (named Lookup), however, these are replaced with "using" references using the methods described in Working With Large Models In Entity Framework. However, what makes my case slightly more unique is that I'm also separating these models into multiple databases (one per model).
I'm having a problem inserting one of my shared entities into my common DB. It's failing with the error:
The member with identity
'Harmony.Members.FK_ResidentialAddress_ResidenceTypeLookup'
does not exist in the metadata
collection.
That foreign key that it's referring to does not exist on the "common DB". But I'm also not working with the entity on the other side of the relationship (named ResidentialAddress); nor do I even have the context that would contain the other entity initialized (named MembersDb). However, both models are compiled into the same assembly.
There are no navigation properties going from Lookup to ResidentialAddress. Though there is a navigation property in the other direction (which I won't be persisting - only using in memory).
My MetadataWorkspace for the EntityConnection of the CommonDb context was explicitly initialized with only the SSDL/CSDL/MSL for the data required for that database. I have confirmed there is no references to the foreign key mentioned in that set of schema data.
var metaAssembly = typeof(CommonDb).Assembly;
var schemaResources = new string[]
{
String.Format("res://{0}/Common.ssdl", metaAssembly.FullName),
String.Format("res://{0}/Common.csdl", metaAssembly.FullName),
String.Format("res://{0}/Common.mdl", metaAssembly.FullName),
}
MetadataWorkspace metadata = new MetadataWorkspace(schemaResources, new []{ metaAssembly });
EntityConnection connection = new EntityConnection(metadata, myDatabaseConnection);
POSSIBLE CLUE: It does work when I go into the generated classes and remove all of the EdmRelationshipAttribute attributes along with their paired EdmRelationshipNavigationPropertyAttribute from the related models (MembersDb).
Key questions:
So why is it that Entity Framework is trying to do something with the relationship that is for an entity that is neither in scope and nor will it be affected by the insertion of the record!?
I am happy to have the generated code remove the attributes mentioned above, but I still want the navigation properties to remain. How would I go about altering the CSDL to achieve that?
NOTE: Persistence of the "child" models is not a priority, nor is the integrity of their now cross-DB foreign keys. These databases are persisted using SQL CE but they were originally generated from a single master SQL Server database.

If each part of your model is written to a separate database, then perhaps the edmx files should not know about each other (about entities or relationship to entities that do not belong to them).
How about trying one of the following approaches:
(To end up with same entities classes for each part, but make EF oblivious of connections between them.)
Remove the "usings" from edmx + cancel auto generation and create classes yourself.
Remove the "usings" from edmx + modify t4 template to read more than one edmx when creating the classes.
Copy edmx files aside so you have two sets of edmxs.
3.a. Use set #1 for auto generation of entities.
3.b. Modify set #2 by removing the "usings" and use for generation of repository classes (objectsets).
Let me know if one of these works.
Good luck,
Danny.

Related

Entity Framework 6.0 SQL-first synch with database without .edmx?

I have a database with some tables for school related project and I have a model with EF 6.0 SQL-first approach. I need to update the database with a new table & update an existing table with a new column. The twist is: I don’t have any *.edmx file.
How can I update the model without it? If it is impossible, then how can I generate *.edmx without interrupting the existing model?
Entities are essentially POCOs, so you really just need to update your schema and update the entity classes to match. For new entities if the project is not using an edmx then it should either be using classes extending EntityTypeConfiguration or setting things up with the modelBuilder on the OnModelCreating event in the DbContext.
EF can resolve most general mappings using convention, so adding a column to a table usually just means adding the property to the entity. Mapping only comes into play when you want to change a columns naming, handle type casting differences, or use identity/computed columns. For new entities it can also use convention, but commonly there would be config used for the Table name, PK name, and things like Identity columns, plus navigation properties for related entities.

Can I Make Entity Models Singular After Import in Database First

I have been using the Entity Framework, database first design for sometime now which means I've got many references to hundreds of Entity models in code that have been imported based on the name of the database table, of which some are singular and others are plural.
I would like to use the built in function that Entity allows when importing models to automatically make these models singular or plural in code regardless of the database table name however that function only seems to be work when adding NEW models.
QUESTION:
I don't want to have to delete all of my Entity Models and re-import because then my code wouldn't match up to a model without manually changing the many references to those objects. Does anyone know of a way to do this?
If anyone is unsure of what I'm referring to:
Entity Framework does not provide this refactoring functionality.
I ended up removing all models and reading them into my project with the proper naming scheme and then manually refactored all references to the models in code.

EF Include() between contexts?

I have two extended instances of DbContext that I use in my code-first solution. One is only ever read only as it maps to an existing set of tables for demographic purposes. The other context is mapped to a local working set of tables.
I have created a view and mapped it to its own entity that is included as a navigational property in a POCO model representing an entity that's mapped to the other context. So my question is: can I use Include to fetch related entities across contexts? So far this doesn't appear so as it complains that it's looking for the view under the wrong schema - the one used for the other context - even though the view clearly has the correct schema defined in its mapping.
I'm using EF 6 with MVC 4.
Each context runs in complete isolation and you cannot share objects from one context to the other. Even if you pull the objects from the database in notracking mode, the moment you associate those objects in the other context by assigning them to navigation properties you are effectively pulling them into the other context which you don't want.
If you have a readonly context of some kind then what you can do is only fill in the foreign keys ids in the read/write context.

Uploading data with entity framework

I am uploading a lot of data to a database using entity framework. I have a lot of different entities with relations between them.
My problem is that sometimes the object I'm uploading might already be in the database, but when I look up that object and find it, I can't add it to my locally made entities, because they belong to different contexts.
For example, I have the entities Sailor and Booze, which have a relation. I have a new sailor Ackbar and I know his favourite booze is rum and I want to persist this to the database.
I make a new sailor and set its name to Ackbar. Then I look up to see if Booze has an entry called rum. If it has, I try to add it to Ackbar. When I do this, EF complains that the new sailor and the booze from the database belong to different contexts.
If I try to attach sailor to the context, it complains that sailor has a null entity key.
How can I build all these relations without saving anything to the database before I'm done editing the relationships?
I suggest that you alter your code to use the same Context for reading and writing. Having multiple contexts for a single transaction is not a better option than having a Context that's alive for a few minutes.

"Update Model from Database" wizard is deleting mappings of renamed POCO classes

I'm building an application using EF 5 to talk to an existing Oracle database. I'm not allowed to change any part of the DB schema. I have generated my model from the database using the VS2012 wizard, and all classes are named after their Oracle counterparts.
The naming of objects in the database is QUITE_UGLY_AND_INCONSISTENT, so I'd like to rename the POCO classes and properties. I can easily do that from the EDM Designer. As a result, I get neatly named class and property names, that are mapped to the UGLY_NAMED tables from the DB. I can successfully perform queries and everything works smoothly. Exactly what I wanted.
However, when I need to add new tables to the model, I run the "Update Model from Database" wizard and check the additional tables to import. It suddenly lists my renamed (but still correctly mapped) classes under the Delete tab, saying it can't find them in the database. When I click Finish, my existing classes are unmapped and I have to manually re-map each property to its corresponding DB column... Or roll back to the previous version of the EDMX file from version control.
I'm looking for what you think would be the most elegant solution to this problem, since I need the application to be as maintainable as possible. I strongly favour an approach that lets me auto-generate new classes from the database while preserving the existing renamed objects and their mappings.
Am I overlooking some way to prevent the Update Model wizard from deleting my existing mappings?
Should I use a different approach to renaming the generated classes?
Should I leave the generated classes unchanged and instead construct sanely-named wrapper classes that are exposed to the rest of my application?
Should I refrain from auto-generation and instead go for a code-first approach? This is a very unfavorable option, because I need the time spent on manual model coding and mapping to be as little as possible. Adding objects will be a very frequent task.
Should I perhaps even use a different ORM altogether..?
I discovered the culprit myself: running the "Generate Database from Model" wizard due to a recommendation in an article I read somewhere. It changed all the model's underlying table and column names to SQL Server standard names ([dbo].[Customers].[CustomerID] etc.).

Categories