正确的实体框架实践

时间:2014-05-20 12:23:24

标签: c# asp.net-mvc entity-framework asp.net-mvc-4

在MVC音乐商店(http://www.asp.net/mvc/tutorials/mvc-music-store)中,作者创建了一个名为MVCMusicStoreEntities的类,如下所示:

namespace MvcMusicStore.Models
{
    public class MusicStoreEntities : DbContext
    {
    public DbSet<Album> Albums { get; set; }
    public DbSet<Genre> Genres { get; set; }
    public DbSet<Artist> Artists { get; set; }
    public DbSet<Cart> Carts { get; set; }
    public DbSet<Order> Orders { get; set; }
    public DbSet<OrderDetail> OrderDetails { get; set; }
    }
}

我可以看到为什么这样做了,它使模型可以通过实体框架轻松访问所有数据库数据....这感觉有点“肮脏”#34;对我来说。

这是正确的做法,将您的所有DbSet放入一个继承自DbContext类的类吗?

我自己写一些东西,我需要使用:

public virtual DbSet<User> Users { get; set; }

public virtual DbSet<Category> Categories { get; set; }

有些情况下,我只希望模型使用Users而不是Categories,因此将它们包装在类似废物的类中。

我可以将DbSet<User>包装在一个类中并将DbSet<Category>包装在一个单独的类中,但实体框架也希望使用包装类的名称作为连接字符串名称...所以如果我想从DbContext继承多个类,我需要多个连接字符串?这是不好的做法吗?还有更好的方法吗?

我可以在方法中动态使用DbContext吗?而不是创建一个继承自DbContext

的包装类

5 个答案:

答案 0 :(得分:2)

我的建议是不要担心这个。将所有DbSet添加到DbContext并仅使用您需要的DbSets。这将花费更少的时间来实施。如果你担心性能,无论如何差异都是不明显的。实体框架仅在您查询数据时加载数据。

答案 1 :(得分:1)

在实体框架中:1 DbContext = 1数据库。您的DbContext是您的工作单位,每个DbSet都是一个存储库。 DbContext仅适用于您的应用程序(整个应用程序)需要从特定数据库访问的所有内容的一站式商店。

如果您想要将某些数据集的访问限制为仅限于应用程序的某些区域,那么 DbContext的任务。相反,它是一个自定义服务类的任务,它将在内部与您的DbContext一起使用,但只暴露某些端点。

答案 2 :(得分:0)

好问题。 你刚开始走在Enterprise Patterns的路上, 在这种情况下,您需要存储库工作单元模式:

  

存储库和工作单元模块旨在创建一个   数据访问层和业务逻辑之间的抽象层   应用程序层。实施这些模式有助于隔离   您的应用程序来自数据存储中的更改

看一下这个基本样本:http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

祝你好运。

答案 3 :(得分:0)

即使您没有使用包装类,也可以在dbContext中将您的表作为this.Set<EntityType>()(返回DbSet<EntityType>)。所以从本质上讲,你的包装类只不过是默认方法的简写。

如果您愿意,甚至可以将它们变成自动属性:

public DbSet<Album> Albums { get { return this.Set<Album>(); }

答案 4 :(得分:0)

另请注意,如果您确实选择了多个DbContext,那么您并不需要多个连接字符串。你可以让你的上下文重用相同的连接字符串,因为你可以在DbContext的构造函数中明确指定它的名字:

public class UsersDbContext: DbContext
{
    public UsersDbContext(): base("name=ConnectionStringName") { }
    ...
}

public class CategoriesDbContext: DbContext
{
    public CategoriesDbContext(): base("name=ConnectionStringName") { }
    ...
}

有两种表格可供选择:base("ConnectionStringName")base("name=ConnectionStringName")。更多详情:http://msdn.microsoft.com/en-us/data/jj592674

另一件需要考虑的事情是,当您使用多个上下文时,使用迁移会变得更加困难。