Separating DbContext in multiple projects - entity-framework

I created a company MVC4 "template" which contains basic helpers, user functions etc, just stuff that is needed in every project.
Now I am trying to separate the Users part which consists of 3 parts: controllers/models/views, a business layer and a data layer.
Now I ran into the problem that I pulled out the data layer part and put it in a seperate project which will become a private Nuget package.
But the package won't know about the DbContext because it's in the DataLayer from the actual project website.
The DbContext for the website currently looks like this:
public class DataContext : DbContext
{
....
public DbSet<Language> Languages { get; set; }
public DbSet<User> Users { get; set; }
....
public DbSet<Reservation> Reservations { get; set; }
....
}
The Languages and Users will go in a separate project/NuGet package and Reservations will remain on the website as it is site specific.
The Languages and Users tables have no reference to each other, but Reservations has a reference to both User and to Language.
What are the options here to still keep a full Code-First model including migrations. Could I create multiple DbContext for every project/NuGet separately, will code-first migrations be able to pick this up, or is there a better way?

If your Reservations contains links to Language and User classes then you will have to use the same Context.
If you want more loosely coupled implementation, then just include IDs instead of actual classes, then you can use separate contexts, but you will loose the ease of referencing objects and so on. The implementation really depends on how big your project is and how you plan on updating the solution.

Related

How to use single context for domain entities and user identities

I'm working on small asp.net core project, where I'm using EF core with SQL server.
So far I've got following configuration:
Db context for my domain entities:
public class AppDbContext: DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options)
: base(options) { }
public DbSet<Request> Requests { get; set; }
public DbSet<Ticket> Tickets { get; set; }
public DbSet<Project> Project { get; set; }
public DbSet<QA> QA { get; set; }
public DbSet<ProjectOwner> ProjectOwner { get; set; }
}
AppIdentityDbContext scaffolded automatically by Visual Studio:
public class AppIdentityDbContext : IdentityDbContext
{
public AppIdentityDbContext(DbContextOptions<AppIdentityDbContext> options)
: base(options)
{ }
public DbSet<IdentityUser> User { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
}
Can I put these contexts in single context? As far as I know they inherit from different base contexts, so my solution rely on two separate contexts so far. I'm not sure if there is any advantage to keep two contexts rather than one, especially in case of small application. After reading this thread I don't think my solution need two of them. As a beginner I'd like to keep it super simple, so how could I achieve it?
Many thanks!
You can base your application DbContext off IdentityDbContext to serve the standard EF integrated authentication, or provide your own authentication implementation that uses your regular DbContext-based application context. However, I generally recommend leaving these concerns separate. This is an example of employing a bounded DbContext. The IdentityDbContext serves its purpose without polluting it with concerns of the application data. Often though you may want to "link" data rows to a User (i.e. CreatedBy/ModifiedBy) which then raises the question of having user apparently in a separate DbContext. For this I will declare a simplified User entity to reference in the application DbContext definition containing just the properties that are relevant for the typical usage.
Given a table called Users with references for credentials, passwords/tokens etc. but also might have application specific details:
The AppIdentityContext sees an IdentityUser which exposes the User ID, credentials, etc. needed for authenticating and authorizing a user.
The AppContext sees a User which exposes the User ID, e-mail, and any app details appended or linked to the user table, but exposes no Authentication/Authorization details.
Both entities are linked to the same table, but serve the separate concerns.
It doesn't make sense to be able to have code like:
var order = _context.Orders.Where(x => x.OrderId == orderId).Select(x => new
{
x.OrderId,
x.OrderNumber,
x.CreatedBy.UserId,
x.CreatedBy.Credential.PasswordHash // <- Not an application concern.
}).Single();
Whether intentional by a dev or accidental, application concerns for a User should not have the potential to expose or tamper with details relating to authentication or authorization. This would be especially important if the code was doing something like serializing entity graphs.
If I want to support something more administrative within the application, or a separate app for managing users, that would be its own DbContext definition again with higher exposure for the fields across both application and Auth concerns. This admin context & functionality would expose both application and authentication/authorization details:
The AppAdminContext sees a FullAppUser which exposes the User ID, e-mail, all app details as well as the Authentication/Authorization details. Functionality that can create/edit users, adjust roles, reset passwords, as well as administer application specific details would use this DbContext and the full user to manage all aspects of the user.
It may seem like overkill for a simple app but it is a good practice IMO to demonstrate the separation of concerns.

Why Navigation Properties are virtual by default in EF

I have following POCO class being used in EF 6.x.
My question: Why is the navigation property of 'Posts' under 'Blog' entity declared as virtual?
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public string Tags { get; set; }
public virtual ICollection<Post> Posts { get; set; }
}
If you define your navigation property virtual, Entity Framework will at runtime create a new class (dynamic proxy) derived from your class and uses it instead of your original class. This new dynamically created class contains logic to load the navigation property when accessed for the first time. This is referred to as "lazy loading". It enables Entity Framework to avoid loading an entire tree of dependent objects which are not needed from the database.
In some circumstances, it is best to use "Eager Loading" instead, especially if you know that you will be interacting with related objects at some point.
Julie Lerman really is the authority on all things Entity Framework, and she explains this process very well in her MSDN Article Demystifying Entity Framework Strategies: Loading Related Data
Eager loading with Include is useful for scenarios where you know in advance that you want the related data for all of the core data being queried. But remember the two potential downsides. If you have too many Includes or navigation paths, the Entity Framework may generate a poorly performing query. And you should be careful about returning more related data than necessary thanks to the ease of coding with Include.
Lazy loading very conveniently retrieves related data behind the scenes for you in response to code that simply makes mention of that related data. It, too, makes coding simpler, but you should be conscientious about how much interaction it’s causing with the database. You may cause 40 trips to the database when only one or two were necessary.
If you are developing a Web Application where every communication with the server is a new context anyway, Lazy Loading will just create unnecessary overhead to maintain the dynamic class for related objects that will never be loaded. Many people will disable lazy loading in these scenarios. Ultimately, it's still best to evaluate your SQL queries which EF has built and determine which options will perform best for the scenario you are developing under.

Entity Framework context format

I'm just now learning MVC4 and Entity Framework. Some examples I have seen have all the "DbSet"s in one class, other I have seen each model have the DbSet in it. Is there an advantage of one way or the other? I kinda like having ONE "MyDbContext" model that references all the other models, but not sure which is better. Any thoughts and real life issues with either way?
public class UsersContext : DbContext
{
public DbSet<UserProfile> UserProfiles { get; set; }
}
public class UsersPostsContext : DbContext
{
public DbSet<UserPost> UserPosts { get; set; }
}
Verses:
public class MyContext : DbContext
{
public DbSet<UserProfile> UserProfiles { get; set; }
public DbSet<UserPost> UserPosts { get; set; }
}
The first example is definitely not the way to go.
It defeats the power of EF to handle complex object graphs. What if you want to retrieve users and their posts and profiles from the database? (Just a random example). You'd need three contexts and a lot of cunning to put the right objects together. And that's only the reading part. CUD actions are even more complex, if only the logic you need to do inserts/deletes in the right order and set FK associations.
That does not necessarily mean that, consequently, you should always have one context class. It can be beneficial to have several of them for parts of the database that logically belong together and are relatively isolated from other parts (like authorization tables, CRM tables, product tables, reporting, ...). In this case you may decide to use bounded contexts.
I use the second notation because that context is more flexible to use. You don't have to wonder which object to pass to the service for example. You don't have to manage a numer of files so it is easier to understand database schema.

How do I handle persistence and unit of work in DDD using Entity Framework?

I'm a little overwhelmed with all of the information on DDD, unit of work, domain services, app services, etc. I'm trying to figure out how a persistence-ignorant domain model ultimately gets persisted, specifically in the context of unit-of-work and Entity Framework. Let's say I have an Order aggregate root, which I am attempting to keep in my persistence-ignorant domain model (the core of my architectural onion):
public class Order : EntityBase
{
public int Id { get; private set; }
public int MarketplaceId { get; private set; }
public int CustomerId {get; set;}
public List<OrderItem> Items { get; private set; }
public List<OrderComment> Comments { get; private set; }
public void AddItem(OrderItem item) { /**add item**/ }
public void AddComment(OrderComment comment) { /**add comment**/ }
public override bool Validate() { /**validate**/ }
public void Cancel() { /**cancel**/ }
}
Let's say I have a process that updates a property on the Order entity, for example it changes the CustomerId associated with the order.
I have an IOrderRepository in my domain layer, which would have an implementation (in an outer layer) with a function like this:
Order GetOrder(int orderId)
{
//get entity framework order, items, etc.
//map to domain-layer order and return domain-layer order
}
void UpdateOrder(Order order)
{
//get ENTITY FRAMEWORK order, order items, order comments, etc.
//take DOMAIN order (passed in to this function), and update EF items fetched above
//use a single EF unit of work to commit these changes
}
There's something wrong with my approach. The UpdateOrder function seems heavy for a small change; but it also seems I have to do that if my repository isn't aware of which items on the persistence-ignorant domain model have changed. Should I be handling every type of update in a separate repository function? UpdateMarketplace(int marketplaceId), UpdateCustomer(int customerId)?
As I'm typing this, I'm also wondering...maybe the way I have it above is not too heavy? If I change one property, even though I'm doing all of the above, perhaps Entity Framework will recognize that the values being assigned are the same and will only send the one db column update to SQL?
How can I take my Order domain model (fetching is straightforward enough), perform some operation or operations on it that may be limited in scope, and then persist the model using Entity Framework?
You need to look into the Unit of Work pattern. Your UoW keeps track of the changes, so when you get your order from your repository and modify it, you call UnitOfWork.SaveChanges() which should persist all the changes.
Using Entity Framework, your DbContext is basically the Unit of Work but I would create a simpler interface around it so you can abstract it away for easier usage in your higher layers.
Regarding EF, I would recommend mapping your domain entities directly using the code first approach. I would also turn off lazy loading and all the magic stuff so you have full control and less "surprises".
Unfortunately I'm not allowed to share our code but we have all this working pretty effectively with the new EF6 Alpha 3. I would recommend you taking a look at Microsoft Spain's nlayerapp for some implementation examples. I don't agree with many of their design decisions (also, see this review), but I think you can draw some inspiration from the Entity Framework parts. Take a look at their Unit of Work implementation and especially how they have abstracted it away for easier usage in the higher layers, and how they use it in their application services.
I will also recommend looking into creating a generic repository to avoid duplicating lots of logic in your aggregate specific repositories. MS Spain has one here, but you should also take a look at this thread.
Please have a look at this SO question where I gave an example of how I've implemented UoW & Repositories.
As #Tommy Jakobsen told you, your domain entities should be your EF entities, it would avoid you to add a useless mapping layer.
Hope that helps!
You may check ASP.NET Boilerplate's Unit Of Work implementation: http://www.aspnetboilerplate.com/Pages/Documents/Unit-Of-Work
It's open source project, you can check codes. Also, you can directly use it.

Building business logic on top of entity framework 5 POCOs

I've got an ADO.NET background and its the first time I've used Entity Framework in a serious project so I've gone ahead and got VS2012 and am using .NET 4.5 and entity framework 5.
I'm taking the data first approach and have created the database, generated the .edmx and also seperated out the POCOS from the context using this method: http://allen-conway-dotnet.blogspot.co.uk/2013/01/separating-entity-framework-poco.html
So my solution looks like this:
Data.Access (where I access the EF context and return POCOS to Business Layer)
Data.Model (where the POCOs are)
Data.Repository (where the context sites)
Presentation.Admin.Website
Now say I have the following table in the database / POCO class (just an example - not real)
namespace Data.Model
{
using System;
using System.Collections.Generic;
public partial class Car
{
public Car()
{
this.Parts= new HashSet<Parts>();
}
public int ID { get; set; }
public string Manufacturer { get; set; }
public string Model{ get; set; }
public Nullable<bool> Enabled { get; set; }
public virtual ICollection<Parts> Parts{ get; set; }
}
}
Now say all the cars in the database have an web service or even just a link to a URL which returns XML and gives me a list of available parts. The way in which each car retrieves the parts data is different (some are REST, some WCF, some from a CSV file, etc).
So I want to define classes that extend Car and define a "GetParts()" method which will have specific business logic to get parts for that particular car.
I also want to be able to get all cars from the database and loop them, calling the GetParts method for each one to retrieve the data.
I am thinking I need to define an interface or abstract class ICar declaring the GetParts method and somehow incorporating the Car POCO but getting confused about how to go about coding this.
Can anyone explain briefly how I can structure my code to get this done, perhaps suggesting a design pattern?
I'm taking the data first approach
The way in which each car retrieves the parts data is different (some
are REST, some WCF, some from a CSV file, etc).
Considering your type of data store is variable and you presumably want a reusable model then I think the choice of using EF database first is not a good one for you. Better to go with code first.
So I want to define classes that extend Car and define a "GetParts()"
method which will have specific business logic to get parts for that
particular car.
Your model should be persistence ignorant. I would not consider extending or hardcoding a data store specific GetParts() if that's what you are after.
perhaps suggesting a design pattern?
Perhaps look into using a repository to provide a layer of abstraction over your data mapping.