EF 6.1.3 with "linked server" - entity-framework

I am using the SQL Server 2012 and EF 6.1.3
I have a central database A and another database B which is linked to the database A. The two databases are used for two different applications.
In the database B I have some views which is exactly as some table in the central database A.
What I am expecting is that when I insert/update/delete records in views of the database B, those records will be inserted/updated/deleted in the central database A.
For the application using the database B (this is the linked server, not the central database), I am using the EF to generate views (using power tools). Code generated looks fine, but, certainly, the generated entity doesn't have primary key properties, doesn't have navigation properties as well.
Can you help with a solution?

EF (Power tools) uses the system tables to retrieve the schema and if you run power tools on database A the navigation informations about linked tables cannot be retrieved. Probably the best way could be that you generate the classes for database B starting from database B (deleting same classes generated starting from database A) then mix the two databases.
At the end you mix the two models (adding navigation properties from model of A to model of B and vice versa).

I had a similar situation once, my problem was with a Stored Procedure in database B (I had access to this object via Linked Server in my Central Database, let's call it Database A. It was not possible to map Database B due to a few company policies), EF 6 does not let you map this Stored Procedure in your EDMX file when using the Database First approach, so what I figured out is a way to trick Entity Framework.
It's pretty simple, I just added an SQL Synonym in Database A, this object points to the View/Stored Procedure/Table in Database B (See attached picture)
Of course, I created the synonym for the Stored Procedure in Database B in my case, then in a method I executed the stored procedure like this:
SqlParameter paramNumber1 = new SqlParameter("#firstParameter", someVariable);
//We need to create a class for the Synonym result, which origin is: [Server].[Database].[dbo].[RemoteStoredProcedure]
var result = ctx.Database.SqlQuery<classForTheSPResult>("RemoteStoredProcedure #firstParameter", paramNumber1).ToList();
If you take this approach, you can perform a Raw SQL Query from your synonym View. For further information, check some the MSDN site, the query would look like this:
using (var context = new BloggingContext())
{
var blogs = context.Blogs.SqlQuery("SELECT * FROM dbo.Blogs").ToList();
}
I hope my comments have been helpful.

Related

What's the point of running an EF migration when you can SQL directly in database?

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.

Entity Framework 4.0 - EF - maps many-to-many relationships too well in the diagram

Sorry I don't speak EF lingo that well, having just set up my first EF project. I'm used to working with Linq-to-SQL as a way of avoiding SQL queries, and it worked well with some WCF web services I used. All this in Microsoft Visual Studio 2010.
Now with that background, I created a database using Servr that has Tables A and B in a many to many relationship with Table C. Since it is illegal to do this in database theory, I set up a linking table, as is well known. Two of them: one called A_C, and the other called B_C, each having a foreign key (1 to many) from tables A and B, respectively. Then I linked table C t both these linking tables, with these linking tables receiving a foreign key from C. So now I am OK I thought.
So I create an ADO.NET entity data model, using the Entity Data Model Wizard, I picked the option "from an existing database", and clicked the buttons. Much to my surprise, and chagrin, and shock and awe, I saw ONLY THREE TABLES: A, B and C! No linking tables whatsoever. Are they kidding me?
Think about this for a moment. The engine that runs the EF figured out that tables A and B share a "many-to-many" relationship with Table C. In the schema diagram of the .edmx file there is show asterisks between A,B and C, exactly as expected.
BUT NO LINKING TABLES ARE SHOWN IN THE SCHEMA! What? It's very logical I suppose not to show the linking tables...but unexpected.
Is this your experience, for anybody who has ever done many-to-many table relationships?
BTW, before I hit the Send key, I did a lot of research on EF 4.0, and I find it is a work in progress it seems. Lots of pitfalls, that I will probably fall into. For example, I intend to deploy this in a WCF REST solution that uses web methods that work with a SQL Server database. In the past I've used Linq-to-SQL and now I am going to try, guardedly, to use Linq-to-Entities.
That is exactly what is supposed to happen. And all three tables will be updated correctly.

Entity Framework model-first design not won't let you edit the table mappings?

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.

EF model mapping multiple databases

I have a model in my project that maps to a LOT of views in my database, but I need to map to a view in another database.
How can I do this? Do I have to create another model? I don't want to, but I will if I have to.
The same model can't get data from the two different DBs. The easiest way would be to create a view in the same database that calls and returns data from the other database i.e. the abstraction view that internally calls external DB view.
If your database supports synonyms, you could setup a synonym to the other database, and merge the edmx definition in with your 1st database's definition. I wrote how to do it here
Basically you end up with two edmx files, and a script that merges the two into a working edmx file. Synonyms are used to reference one database from the other without needing the full database path.
If you use code first approach in Entity Framework, here is how to map EF entity to the table from other database:
SQL Script that needs to be run in your database to create synonym for the table from other database:
CREATE SYNONYM OtherDatabaseTableSynonym FOR otherdatabase.dbo.otherdatabasetable
Entity Framework Mapping in (Fluent API):
modelBuilder.Entity<OtherDatabaseTableEntity>().ToTable("OtherDatabaseTableSynonym").HasKey(x => x.id);

Entity framework 4 and multiple database

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