Setup
I have a SQL Server 2008 database that is accessed using the Entity Framework on the server.
Each client has a SQL Server Compact Edition 3.5 database for storing data when offline.
I use self tracking entities that are generated from the server defined Entity Framework.
Question
At the moment i have two EDMX defined, one for the server and another for the client, even though they are identical except for the storage provider. I use the self tracking entities from the server and they work fine with the client database. Is there a way to have just a single EDMX? At the moment there is a risk I will make a change to one EDMX and forget to make it to the other. Or am I using the wrong approach?
Note
I do not want to use the sync framework because of complex business logic that needs applying at the server side.
Unfortunately there is no direct way to use single EDMX with multiple storage providers. You must always have separate SSDL part for each provider. The common workaround is to export SSDL, MSL and CSDL as separate files (default setting adds them as resources to assembly) and use some script or pre-build action to create copy of SSDL file with all necessary changes for second provider (there can be also different data types between SQL Server and SQL Server CE). You will than use correct SSDL file per application by specifying it in connection string.
Another "better" solution is not using EDMX and use code first where this problem mostly doesn't exist - but that is architecture change.
Related
How to create View (SQL) from Entity Framework in ABP Framework
Not allowed to post comments because of reputation. Just trying to get more information on connecting a database to an Entity Framework, without having to switch to a code-first development style. View selected answer's response (he told the OP to basically do the same thing he was going to do in the DB but with EF, and then added an extra step where EF "...ignores..." the previous instructions...
I want to create tables and design database directly in SQL, and have the csharp library just read/write the table values (kind of like how dapper function where it isnt replacing your database, just working along side of it).
The tutorials don't talk about how to integrate your databases with your project. It either brushes over the subject, ignores it completely, or discusses how to replace it.
I don't want to do any EF migrations (i dont want/need to destroy/create database everytime i decide to run, duplicate, or transfer project). Any and all database back-track (back-up/restore) should be done with and thru SQL (within my work environment).
Just to be clear on exactly what i'm trying to learn:
How does somebody who specializes in database administration (building database schema, managing and monitoring data, and has existing database with data established) connect to project to fetch data (again, specifically referencing Dapper's Query functionality).
I want to integrate and design micro-services, some may share the same database connection or rely on another. But i just simply want to read data in a clean strongly-typed class entity, and maybe deal with insert/update somewhere else if i have to.
I would prefer to use Dapper instead of EF, but ABP is so heavily integrated with EF's design, it's more of a headache to avoid it, than it is to just go along with.
You should be able to map EF under ABP the same way as any other project using DB-first configuration.
The consistent approach I use for EF: (DB-First)
Define entities to match the table/view structure.
Define configuration classes extending EntityTypeConfiguration<TEntity> with the associated ToTable(), HasKey(), and any HasMany/HasRequired/HasOptional for relationships as needed.
In DbContext.OnModelCreating: modelBuilder.Configurations.AddFromAssembly(GetType().Assembly); to load all entity configurations. (assuming DbContext is in the same assembly as the models/configurations Substitute GetType().Assembly to point at the entity assembly.
Turn off Migrations. In DbContext constructor: Database.SetInitializer<MyDbContext>(null);
EF offers a lot more than simply mapping tables to classes. By mapping relationships between entities, EF can help generate optimized queries for retrieving data across those related entities. This can allow you to flatten data structures without returning unnecessary data, replace the need for views, and generally reduce the amount of data coming across the wire from the database to the application server.
I'm currently assign to a project where their legacy system is designed in a horrible way and it's been too much focus on database design. I trying to put together a new design where the customer can migrate the legacy system bit by bit.
They are currently using EF 4.1 BUT not code first approach with entity descriptive/mapping is located in an edmx file. They do Reverse engineering everytime to want to extend the model (First make changes in database, then reflect them upwards to Model layer through a custom tool).
What I would like to know, if anyone has used BOTH edmx and code first approach with mapping classes. And is there drawbacks to know about?
You can use EDMX and code mapping together only if you have separate context type for each approach (you cannot mix approaches in single context type). That is probably the biggest disadvantage because it leads to more complex code and maintenance.
For example if you need to have some entity in both contexts types to use it with both new and legacy code you must maintain its mapping twice. You must also be very careful about not duplicating entity class itself = your code first must use class generated by custom tool for EDMX but this will not be possible if they are not using POCOs in current solution.
Another problem will be database integrity. If you will need to save changes to both context types in single transaction you will have to use TransactionScope and distributed transaction = MSDTC (each context instance will handle its own database connection).
If you are sure that whole system will be migrated you can probably think about using code first instead of EDMX (but be aware that code first mapping and DbContext generally offers more limited feature set). If you are not sure that you will be able to complete whole migration don't even think about using code first because leaving system in the state where half uses code first and half EDMX will make everything only worse and much more horrible.
Being sure is little bit theoretical because in SW development the only think you can be sure about is that requirements / situation will change. It means that migration should be very carefully considered.
I also was struck with this problem. What I found was that you can model the database and "generate the database from the model" in a "Ado.NET Entity model Project".
But you can not create stored procedures in that project, What only you can do is you can import the stored procedures from the server.
But if you do not want to create stored procedures on the server, you can create another project on VS, "SQl CLR Database Project" and you can code your stored procedures and tigers in that project and deploy them to the server.
then you can again import these stored procedures from the "Ado.NET Entity model Project" by "Update Model From Database".
Like wise you can develop your server project using both approaches(Code first and Model first)
Hope this will add something more :)
If we've been using an Entity Framework 4 model for some time, and we eventually want to switch the underlying database to a different vendor's product (say, from SQL Server to MySQL), is it simple to adjust the table and column mappings in the entity model without needing to update any of the entity class code?
We're trying to design code that is as database agnostic as possible, so I'd like to know in advance how much trouble we're in for if we ever switch our databases around. Ideally, we'd like to not have to touch our applications that use our entity classes. I can't seem to find any way in the entity designer or XML editor to adjust the underlying database column names without it giving me an error.
(I can, however, edit the entity's property names in the designer while leaving the database column names alone, but that's the opposite of what I need.)
Thanks!
EDMX is not database agnostic. SSDL part of EDMX is tightly coupled with database server (in case of MSSQL even with its version). You need separate SSDL for each supported database server.
I don't understand how changing column names relates to database agnostic model. Reverse is true! If you need your database to have different column names for different server products you need separate mapping for each of them!
Changing column names when using model first is possible only if you modify T4 template used for generating database creation SQL script. But every time you create that script designer will delete whole your storage description (SSDL) and mapping (MSL) and replace them with a new one.
The easiest way to have database agnostic code is using code first but even then you can have problems with some type and feature inconsistency among servers.
If you want database agnostic ORM you should probably check NHibernate.
I am creating a project using Entity Frameworks 4 and self tracking entities. I want to be able to either get the data from a sql server 2008 database or from sql server compact database (with the switch being in the config file). I am using the repository pattern and I will have the self tracking entities sitting in a separate assembly.
Do I need two edmx files? If so, how do I generate only one set of STE's in the separate assembly? Also do I need to generate two context classes as well? I am unsure of the plumbing for all this. Can anyone help?
Darren
I forgot to add that the two databases will be identical and that the compact version is for offline usage.
Just to follow up on this. In the end I had to maintain two separate edmx files, one for sql server and one for compact. The main reason being that compact 3.5 does not support auto identities (as mentioned above by Zeeshan). This in turn led to two context classes. In the context class for sql server compact I had to put code to check for insertions, query the database for the latest id and increment it manually before saving.
Thankfully with the release of compact 4.0 this no longer applies as it supports auto id and you can indeed use just one edmx file.
Darren
You do need the edmx file as long as the schema is exactly the same. just change the connectionstring and everything would work seamlessly. Though i am not sure how u are saying that schema is same when compact edition does not support identity concept and full blown sql server does. So if you are using features specific to sql server that's not available in compact, then you would get runtime errors.
Something changes or it still not support this?
For example join database1.dbo.Users and database2.dbo.Addresses
I actually did find a way to make an EF model span multiple databases if your database supports Synonyms. Basically you setup Synonyms to Database2 on Database1, create separate edmx models for each, then merge the XML
I posted the exact steps to make an edmx file span multiple databases here if you're interested, along with a script to do the merge for you whenever something changes.
I think what ais asked is if you can join tables from different databases, not different providers, resulting in one entity mapped to two or more tables or views from different databases.
If you think about it, when you create a EDM model with Visual Studio it ask you to give an existing database, and when finished creating the model, it generates an EF connection string, that internally address to the given underlying database connection string.
E.g: metadata=res:///EFTestModel.csdl|res:///EFTestModel.ssdl|res:///EFTestModel.msl;provider=System.Data.SqlClient;provider connection string="Data Source=.\;Initial Catalog=EFTest;Integrated Security=True;MultipleActiveResultSets=True"*
So each model matches only a database, only a connection string.
EF4 still does not support creating one conceptual model which works with N storage models. At least this is not supported with any built-in provider. Perhaps in the future this could be done through a new provider that combines the support of many storages (from the same providers or different).
I havent done enough research on it, but perhaps Windows Server AppFabric (Codename Velocity) could be the bridge to go through this gap.
Note: I have tried even editing manually the xml for the EDM (edmx) to insert a second element inside the <edmx:StorageModels> tag but it does not match the EDM XML Schema so VS warns about it:
Error 10021: Duplicated Schema element encountered.
Rafa Ortega
MAP2010
See answer to similar question:
Entity Framework - Inserting entity with multiple models and databases