entity framework with existing, non related database - c#

I have an odd situation. I am working on a project with a very large existing database that is completely unrelated, but does contain corresponding table id's. It's as if someone copied the database but never related the tables.
In Entity Framework, is there a way to go EF code first and create the relationships in code, but Not apply those relationships in the database? I would like to go through and relate the database but the client doesn't want to pay to fix it.
Thanks!

In this instance, it seems you would be best to add relationships directly to your database (or to a duplicated database for testing/staging) and then just update your entities using your test connection and regression test your app.

Related

EF Core automatically deleting records on Add Operation

I receive a large JSON having different recordsets in the form of arrays in a Xamarin-Forms application. The recordsets are linked with each other through reference Ids. Basically the data is coming from a relational database and I have to map the data into the device's local SQLite. I am using EFCore for that. I am able to successfully set up the Models and their FKs using OnModelCreating override. I have verified it by logging the table creation scripts. Now the issue is, when I AddRange a list of some records, EF Core automatically deletes some of the records. I don't know why and how.
Here is the screenshot in debugging:
The data is a huge graph of different relational records. Earlier I was trying to Add the whole graph by saving only the grandparent record. But there are several children who reference the same record more than once. For example, a UserType is referenced by many users. So EF throws Identity tracking issues. Then I decided to not save using the graph, instead save table by table. And now I am facing this issue. To be specific, there is a total of 11 tables involved in my saving. I am able to save 5 tables that have independent data e.g. UserTypes, EntityTypes, ContactTypes, etc. When I came to the 6th table which references some records of 5 saved tables, I am getting this issue.
Update:
I solved the problem. The issue was in a relationship that was wrongly defined. A WorkOrder can have one Customer only, but a Customer can be linked to many WorkOrders. I was taking it as One-to-One but was ignoring the other way. I updated the one-to-one to one-to-many in Customer entity and everything started working great!
By the way, this we can say the beauty and perfection of EF Core that it can never allow you to persist data against the rules you have defined. Though automatic deleting was a little confusing but ultimately that was my mistake.

Will migrations affect my database?

I am learning Entity Framework to query the database of my company. I have an ASP.NET MVC project and as of now, I have established a connection to the company's principal server database. That has given me access to all the tables and I created a separate class Library containing all the corresponding POCOs(generated automatically).
In the tutorial I was following they say to use "enable-migrations" to have the database updated with the model.
So does that mean that if I were to modify the models in my project, that would have a direct effect on the database? Since I am new to this project I do not want to do anything stupid, like altering the database. For now I just want to query the database and retrieve information, then use that information to show more or less information on a web page.
EDIT: Just as an example, I would like to show a difference between the model generated by EF and what my real table looks like. I have a table Web_Profils that contain and ID, a ProfileName and an Order (int). This DB has no primary keys or foreign keys. If there are relations, they are defined through new tables. But when EF generates all my classes, it adds ICollections, for example in Web_Profils, I have a.o virtual ICollection<Web_User_joint_Profils>Web_User_joint_Profils which is not present in the actual table, it just seems to be the relation that EF has deduced(it is the relation between Users and Profiles present in the table Web_User_joint_Profils). Now, will doing a migration affect my tables just because EF has added these collections in my model?
I've also read that it is possible to deactivate migrations using :
Database.SetInitializer(new ContextInitializerNone<YourDbContext>());
Any thoughts?
If you update your model, you need to add a migration to your project and update your database with that migration.
Unless you do those steps after updating your model, changes will not be reflected in the database.

EF Initializer with multiple contexts for one database

I have an existing application with a SQL database that has been coded using a database first model (I create an EDMX file every time I have schema changes).
Some additional development (windows services which support the original application) has been done which uses EF POCO/DbContext as the data layer instead of an EF EDMX file. No initializer settings were ever configured in the DbContexts, but they never modified the database as the DbSet objects always matched the tables.
Now, I've written a seperate application that uses the existing database but only its own, new tables, which it creates itself using EFs initializer. I had thought this would be a great time to use EF Code First to handle managing these new tables. Everything worked fine the first time I ran the application, but now I am getting this error from some of my original EF POCO DbContexts (which never used an initializer).
The model backing the 'ServerContext' context has changed since the
database was created. Consider using Code First Migrations to update
the database
After some investigation, I've discovered that EF compares a hash of its schema with some stored hash in the sql server somewhere. This value doesn't exist until a context has actually used an initializer on the database (in my case, not until the most recent application added its tables).
Now, my other DbContexts throw an error as they read the now existing hash value and it doesn't match its own. The EF connection using the EDMX doesn't have any errors.
It seems that the solution would be to put this line in protected override void OnModelCreating(DbModelBuilder modelBuilder) in all the DbContexts experiencing the issue
Database.SetInitializer<NameOfThisContext>(null);
But what if later on I wanted to write another application and have it create its own tables again using EF Code first, now I will never be able to reconcile the hash between this theoretical even newer context and the one that is causing the issue right now.
Is there a way to clear the hash that EF stores in the database? Is EF smart enough to only alter tables that exist as a DbSet in the current context? Any insights appreciated.
Yes, Bounded DB contexts is actually good practice.
eg a base context class, to use common connection to DB, each sub class, uses the
Database.SetInitializer(null); as you suggest.
Then go ahead and have 1 large context that has the "view of the DB" and this context is responsible for all migrations and ONLY that context shoudl do that. A single source of truth.
Having multiple contexts responsible for the DB migration is a nightmare I dont think you will solve.
Messing with the system entries created by code first migrations can only end in tears.
Exactly the topic you describe I saw in A julie Lerman video.
Her suggested solution was a single "Migration" context and then use many Bounded DB contexts.
In case you have a pluralsight account:
http://pluralsight.com/training/players/PsodPlayer?author=julie-lerman&name=efarchitecture-m2-boundedcontext&mode=live&clip=11&course=efarchitecture
What EF version are you using? EF Code First used to store hash of the SSDL in the EdmMetadata table. Then in .NET Framework 4.3 thingh changed a little bit and the EdmMetadata table was replaced by __MigrationsHistory table (see this blog post for more details). But it appears to me that what you are really looking after is multi-tenant migrations where you can have multiple context using the same database. This feature has been introduced in EF6 - (currently Aplpha2 version is publicly available) Also, note that EdmMetadata/__MigrationHistory tables are specific to CodeFirst. If you are using the designer (Model First/Database First) no additional information is stored in the database and the EF model is not checked whether it matches the database. This can lead to hard to debug bugs and/or data corruption.

EDMX has no relations present using the database-first approach in EF

I am using Entity Framework to work against a database using the database-first approach, with an EDMX file representing my database. A problem happened when I changed one property in the database, then when I erased it from the EDMX file and updated it to add it again, it shows up now without the relations to the other tables (Pk-Fk relations).
More Info:
1. tried connecting from another new project and same result.
2. tried re-creating the database and re creating the pk-fk relation, and same result.
3. tried connecting to another database with edmx, and in this case the relations were present.
4. in the sql management studio it looks like the relations are present in the tables, as well as in the diagram.
Does anyone knows what is the problem?
When I need to update a table in the edmx it normally creates another .edmx.designer file, if this is happening this could be the reason why the relations doesn't appear. Just delete the older .edmx.designer and it should work again. If this isn't the problem, sorry but I'm new to entity framework, don't know it very well

How to get entity framework to realize the model and the DB are in sync

I am using Entity Framework code first for the first time in a production environment. Everything went fine until we got the DB up and had put some of the data in it and then to get some of the data we were importing from another location we had to change field lengths. So we made some of the fields nvarchar(99) instead of nvarchar(50).
That went fine and the application still worked but I knew I needed to change the data annotation or it would blow up later when it loaded and tried to save a too long field. When I did that the app blew up even though the model and the db are now matching. So I thought that it was the hash in the metadata table so I thought I'd be clever and make a new DB and take the hash from there and copy it. That did not work and in fact now I cannot get my app to connect to the test db that we have data loaded in at all.
I do not want to drop and recreate this database. I want entity framework to realize that the model and the schema do in fact match. Is there any way for me to do this? Also why did copying the metadata from a DB that entity framework created with this model not work?
Entity Framework Code First creates a EdmMetadata table and saves a hash of your Model classes in it. When you change something in the Model, the hash of the new Model classes doesn't match what's in the EdmMetadata table anymore, and the app should "blow up" at runtime. What you need to do to keep using the same database without dropping it, is to delete the EdmMetadata table. This way EF will not do that check and will try to proceed with the access to the DB.
Check this video tutorial (skip to 8:10 of the "When Classes Change" section).
Sorry I fixed this. Removing the metadata worked. But turns out I had updated to a more recent version of EntityFramework accidentally while trying to fix my problem and this more recent version expected different naming conventions for the Database. In any case recreating the many-to-many group person table with a script from a DB created by Entity Framework and deleting the metadata fixed the problem.

Categories