The Users in my database will be related to many other entities. Is the recommended practice for doing this to have 1 db context for the app? Or, should there be two different ones. It seems that I could retrieve the context through the use of the GetOwinContext()
The standard practice with this is to keep all of your tables for your webapp in 1 database (1 context). One large advantage of this is that you can execute SQL joins based on data that is stored in your Identity tables.
Here is a use case: I have a fileupload entity and table which I need to relate to a specific user (the user that uploaded the file). If everything lives in one database then I can use foreign keys and entity framework navigation properties as I normally would. If I was using a separate database/context for the Identity provided tables, then I would need to query two different database (which is more costly performance-wise) to get my needed data. One query to DB1 to get my user Id and another query to DB2 to get the fileuploads which belong to this user Id
So in short, if you have users related to many other entities (which you mentioned) then I would strongly recommend using 1 database and context.
Related
Starting point
(changing some real naming, just to simplify)
The project consists of an ASP.NET MVC 4.7.2 application, with a SQL Server database. The MVC app uses Entity Framework 6, with an entity data model (initially based on database-first model) for current database that generate the classes to manage the database entities.
The objective of the application is to create and digitally sign document instances based on different kinds of documents. The generated instances are simply PDF files.
This database has a table (Instance) that stores each instance file (PDF) as a varbinary (column File), among other instance metadata (creator, date, name, department...), with a unique ID as primary key named InstanceId.
Each instance is created and modified a few times, depending on document type and digital signature requirements. These iterations must take from a day to a year. After finished and completed the digital signature process, the instance would be kept in database for a long time, and the file won't be modified anymore.
After some time (casuistry could vary from 2 to 5 years, depending on base document type), files could be deleted, as some are already stored in a document repository and other are discarded as obsolete.
Problem detected
The amount of files is massive nowadays, and keeps growing up by leaps and bounds. That makes the database hard to manage (backups, synchronization with testing development environments...)
Potential solution
The mainly accepted approach is to keep current database (MYAPP) with same table Instance storing all metadata for each instance created, and create a new database (MYAPP_FILES) with a unique table (also called Instance) that stores only the files (PDF in varbinary column).
The link between tables should be using the same ID in both tables, something like MYAPP.Instance.InstanceId = MYAPP_FILES.Instance.InstanceId.
Creating a view (also proposed in other posts, like Entity Framework with multiple databases) based on Instance table. Using original table to work with it for transactions (create, update), and take the view for queries (depending on date, this could retrieve File column from MYAPP or MYAPP_FILES using the InstanceId to relate both databases/tables).
This requires creating a new entry in the MYAPP_FILES Instance table, based on date column, for some instances. This could be achieved using a SQL Server Agent job scheduled to execute periodically.
Questions
Creating a new EDM to refer and work with MYAPP_FILES database means a lot of effort but, does it have other benefits?
Is there a better solution in terms of efficiency/best practices?
Once created in current EDM, the view does not contain, of course, navigation properties. Is there a way to generate them using EF?
Once created both classes to work with (let's suppose, Instance.cs and ViewInstance.cs) is it possible to use the first for creating / updating actions and the second for queries using repository pattern?
I have a MVC .Net Core 3.1 project with 2 contexts. One is the standard Identity context and the other is the application context.
These are stored as 2 separate databases on the server.
In my application I have an entity 'Project' and it has a field 'ProjectLeadUserId' in which I store the ID of that user from AspNetUsers.
When I list all of the open projects I would like to show the 'UserName' from AspNetUsers, rather than the GUID related to each of the projects.
Normally I would have a foreign key between the two so that in my view I could do something like:
project.ProjectLead.UserName
But I cant workout how to set that up in my entity as the FK would be in a different context.
Is this possible, or have I caused myself an issue by separating the Identity and application contexts?
Edit:
Ignoring the foreign key issue as I can deal with that in the application logic. Is there a way to load the related data when multiple contexts are involved.
e.g. When I get a list of projects, can I load the related AspNetUsers data, using the AspNetUsers.Id and Project.ProjectLeadUserId?
Quoting from SQL Server documentation:
FOREIGN KEY constraints can reference only tables within the same database on the same server. Cross-database referential integrity must be implemented through triggers. For more information, see CREATE TRIGGER.
It's not possible for you to have a foreign key across different databases in SQL Server.
If the 2 contexts targeted the same DB, I think what you want would still not be possible.
In my past projects I've usually seen people extending the IdentityDbContext to create their DB context and using only that.
My team would like to separate User data from our core application data. We're using SQL Server 2014 and EF 6.x Code First. If we create a Users database and an Application database is there any way to tell EF about a relationship between the User object and and Order object? Assuming the Orders are stored in the application database and the users are stored in the Users database. We know that we could instantiate the User from the Users database and then query the Application database for a list of orders, but what we're looking for is a solution that functions as if the tables were both in the same database, such as when a User is retrieved its list of Orders is available without a second call.
Basically, we're looking for a way to map entities to a specific context and then instantiate each context pointing to its respective database and let EF sort out the calls.
Yes, but you need to do some configuration one the database servers.
Your Application database can define a Synonym to the table in the Users database, which you can then map an entity to as if it were a normal table in the Application DB.
As far as Entity Framework is concerned, it uses the same DbContext pointing to your Application database, but it can pull information from your Users database.
One downside with this is that your Application database needs to be setup to point at a specific Users database.
I'm building a new system that utilizes data from an existing legacy system. A requirement is for our application to use the same physical database but a different schema for isolation. Our application will need read access only from the dbo schema, but our new structure will have foreign keys from the dbo schema so we'll need to enforce that.
I'm planning on creating two different projects with two different contexts. This will facilitate using Reverse Engineer Code First from EF Power Tools on the dbo schema, and using EF Migrations on our new schema. However, I'm unsure how this approach will handle Foreign Keys across contexts/domains. How would I map these so Migrations interprets it correctly?
If you use different schemas and\or different contexts, that means this data can be stored anywhere, even at different storages (files, azure, services). You should not use explicit foregin keys across across contexts/domains. You have to make separate queries to each contexts.
If you really need to do that, you can use databse VIEWS with any joins you need (even from other server). Then just map our EF entity to view:
[Table("MyView")]
public class MyEntity {...}
Obviously, it will read-only entity.
I'm working on a project already started by several developers before me. One thing in particular bothers me is that they have single entity split in two databases.
Entity is called Tracker.
First database is called ConfigBase, and it has table named Trackers that has TrackerId along with it's attributes.
Second database is called StoreBase, and it also has table named Trackers, whose elements have matching TrackerId as it is in the first base.
Moreover, to have things even more complicated, when you access specific tracker in ConfigBase, you gain SQL server name and credentials that allow you to access it in StoreBase.
Now all this isn't too much complicated if you use plain old ADO.NET. But as my task is to raise entire solution to newest EF 4.3.1, I'm having troubles maintaining consistency of my entity. Half of things related to Tracker entity are in ConfigBase and the other half in StoreBase, and usually I have to get both to get some result.
Is there any solution to this that does not involve virtual merge on database level. I'm looking for a solution that can be done with Code First modelling.
Thanks in advance!
No there is no solution provided out of the box because EF itself is even not able to use more than one database per context. So you will either merge your databases or you will access each database separately (with separate Tracker entity per database) and merge data somehow in your application.