Where should EF Migrations go, my Class Library project or my ASP.NET project?

你说的曾经没有我的故事 提交于 2019-12-03 14:19:48
joelmdev

Like John said in his comment, you might be served well by moving all of your EF code into a separate class library. I typically create Web, Domain, DataAccess, and Test projects for a new solutions, and split them up even more down the road if it's necessary. This gives you some clear, basic separation of concerns up front. The Visual Studio Web project templates don't provide that, as it's designed to be self-contained in a single project.

Visual Studio's Web template is a good starting point for small projects but it pretty quickly becomes a mess as the project grows. Having the website (which is more or less your presentation layer), domain models & business logic, and data access all in the same project isn't particularly good practice. Partially separating them by leaving your user models and a separate DbContext behind in the web application can be even more confusing IMO, especially if your ApplicationUsers are going to participate in relationships with models from your domain class library.

I would suggest moving your ApplicationUser into the class library that contains your domain models, and take your ApplicationDbContext and move it into a DataAccess class library. You can take that one step further and combine your two DbContexts into one without much effort, unless you suspect that the project will grow large enough to require multiple `DbContexts. At that point, it becomes very apparent where your Migrations should live. Unless you're trying to abstract it away, your Initializer will always go in the application, which in your case is FooBarAsp, so you're correct that Global.asax is the place to set that up.

However, if this sounds unappealing to you and you'd like to keep your project structure as it currently is, it's my opinion that you would be best off configuring migrations for both DbContexts for consistency's sake. At that point, You'd have a set of Migrations in your web project (FooBarAsp) for the ApplicationDbContext that inherits from IdentityDbContext and another set of migrations that resided in your class library (FooBar). Both would need initializers in the Global.asax.cs of your web project.

Edit based on OP's update: I can see where you're coming from in your desire to keep ASP.NET related references out of your domain layer. It's basically impossible to keep this from happening without splitting up your user models in two as you've done. This is something I asked about when VS2013 was still pre-RTM and never got a satisfactory answer because it's currently not possible to have an User model that works with Identity that doesn't pull in some ASP.NET related assemblies. However, in a somewhat analogous situation, the DbGeography type can be a very useful type to include in your domain layer, but it's impossible to use it without pulling in Entity Framework related assemblies. It really comes down to weighing the pros and cons and picking the lesser of two evils- be pragmatic in when and where you apply design patterns.

That said, if you do want to keep the DbContexts separate and the ApplicationUser in your web application, I'd suggest pulling out all the extraneous fields from the application user- in fact, just use the IdentityUser class itself instead of subclassing it since you'll be using it purely for authentication and authorization. However, I believe you'll still need to enable Migrations for both contexts and look into how to use multiple contexts per database with EF6, which wasn't possible in EF5.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!