实体框架 6 代码优先 - 存储库实现是一个好的实现吗?

2024-01-09

我即将使用存储库和工作单元实现 Entity Framework 6 设计。

周围有很多文章,我不确定最好的建议是什么:例如,我真的很喜欢这里实现的模式:出于文章中建议的原因here http://codefizzle.wordpress.com/2012/07/26/correct-use-of-repository-and-unit-of-work-patterns-in-asp-net-mvc/

然而,Tom Dykstra (Senior Programming Writer on Microsoft's Web Platform & Tools Content Team)建议应该在另一篇文章中完成:here 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

我订阅Pluralsight,而且几乎每次在课程中使用它时,它的实现方式都略有不同,因此选择设计很困难。

有些人似乎建议工作单元已经由DbContext就像在这个post http://social.msdn.microsoft.com/Forums/en-US/435bf3a3-a358-41cf-a1b0-9f4387dcf5f2/is-unit-of-work-functionality-already-available-inside-the-dbcontext-in-ef-5?forum=adodotnetentityframework,所以我们根本不需要实现它。

我意识到以前曾有人问过此类问题,这可能是主观的,但我的问题是直接的:

我喜欢第一篇(代码失败)文章中的方法,并想知道它是否比其他方法更易于维护、更容易测试,并且可以安全地继续使用?

任何其他意见都非常受欢迎。


@Chris Hardie 是正确的,EF 开箱即用地实现了 UoW。然而,许多人忽视了这样一个事实:EF 也实现了开箱即用的通用存储库模式:

var repos1 = _dbContext.Set<Widget1>();
var repos2 = _dbContext.Set<Widget2>();
var reposN = _dbContext.Set<WidgetN>();

...这是一个非常好的通用存储库实现,内置于工具本身中。

当 DbContext 为您提供所需的一切时,为什么要费力创建大量其他接口和属性呢?如果您想要抽象应用程序级接口后面的 DbContext,并且想要应用命令查询隔离,您可以执行如下简单操作:

public interface IReadEntities
{
    IQueryable<TEntity> Query<TEntity>();
}

public interface IWriteEntities : IReadEntities, IUnitOfWork
{
    IQueryable<TEntity> Load<TEntity>();
    void Create<TEntity>(TEntity entity);
    void Update<TEntity>(TEntity entity);
    void Delete<TEntity>(TEntity entity);
}

public interface IUnitOfWork
{
    int SaveChanges();
}

您可以使用这 3 个接口进行所有实体访问,而不必担心将 3 个或更多不同的存储库注入到与 3 个或更多实体集一起使用的业务代码中。当然,您仍然可以使用 IoC 来确保每个 Web 请求只有 1 个 DbContext 实例,但所有 3 个接口都由同一个类实现,这使得它更容易。

public class MyDbContext : DbContext, IWriteEntities
{
    public IQueryable<TEntity> Query<TEntity>()
    {
        return Set<TEntity>().AsNoTracking(); // detach results from context
    }

    public IQueryable<TEntity> Load<TEntity>()
    {
        return Set<TEntity>();
    }

    public void Create<TEntity>(TEntity entity)
    {
        if (Entry(entity).State == EntityState.Detached)
            Set<TEntity>().Add(entity);
    }

    ...etc
}

现在,您只需将单个接口注入到您的依赖项中,无论它需要使用多少个不同的实体:

// NOTE: In reality I would never inject IWriteEntities into an MVC Controller.
// Instead I would inject my CQRS business layer, which consumes IWriteEntities.
// See @MikeSW's answer for more info as to why you shouldn't consume a
// generic repository like this directly by your web application layer.
// See http://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=91 and
// http://www.cuttingedge.it/blogs/steven/pivot/entry.php?id=92 for more info
// on what a CQRS business layer that consumes IWriteEntities / IReadEntities
// (and is consumed by an MVC Controller) might look like.
public class RecipeController : Controller
{
    private readonly IWriteEntities _entities;

    //Using Dependency Injection 
    public RecipeController(IWriteEntities entities)
    {
        _entities = entities;
    }

    [HttpPost]
    public ActionResult Create(CreateEditRecipeViewModel model)
    {
        Mapper.CreateMap<CreateEditRecipeViewModel, Recipe>()
            .ForMember(r => r.IngredientAmounts, opt => opt.Ignore());

        Recipe recipe = Mapper.Map<CreateEditRecipeViewModel, Recipe>(model);
        _entities.Create(recipe);
        foreach(Tag t in model.Tags) {
            _entities.Create(tag);
        }
        _entities.SaveChanges();
        return RedirectToAction("CreateRecipeSuccess");
    }
}

关于这个设计我最喜欢的事情之一是最大限度地减少实体存储对consumer

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实体框架 6 代码优先 - 存储库实现是一个好的实现吗? 的相关文章

  • VS2012 中的实体框架问题 - 重命名属性不粘

    我试图在 VS2012 中创建一个新项目 其中包含管理 MVC4 项目 网站 MVC4 项目和通用实体框架 dll 项目 我使用了现有的数据库并从中生成了我的实体 我更新了一些关系属性的名称并保存 然后 我将对实体框架项目的引用添加到我的两
  • MetadataException:无法加载指定的元数据资源

    突然间我不断收到MetadataException在实例化我生成的ObjectContext班级 App Config 中的连接字符串看起来正确 自上次工作以来没有更改 我尝试从底层数据库重新生成一个新模型 edmx 文件 没有任何更改 有
  • 为什么 EF DataBase First 不使用 getdate()?

    我首先使用 EF 4 1 和数据库 示例表 CREATE TABLE dbo Product ID int IDENTITY 1 1 not null Title nvarchar 200 not null CreateDate datet
  • MVC3 和实体框架

    我的问题很简单 将 edmxMVC3 项目的 Web 应用程序的模型文件夹中的文件吗 我的答案非常简单 不要用数据访问逻辑和数据建模搞乱表示层 整个 MVC 应用程序 Visual Studio 解决方案中从下到上至少有 4 个项目 1 P
  • 使用 IQueryable 进行单元测试代码

    我被要求为某些功能编写一些单元测试 但坦率地说 我不太确定这样做的必要性或有用性对于这个特殊的一段代码 我绝不试图质疑单元测试的必要性或有用性 所讨论的代码非常简单并且被大量使用 基本上它是 Skip 和 Take 扩展方法的包装 在我看来
  • 学习实体框架[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Web API 的 ASP.NET MVC Core 控制器 PATCH 方法

    给定一个数据库表 Person 包含 3 列 Id 名字和姓氏 使用真实的 DbContext 时 ASP NET Core Web API MVC 控制器方法 PATCH 仅修改姓氏 看起来如何 我根本不知道如何实现它 并且找不到相关教程
  • 将 ASP.NET Identity 实施到现有数据库中

    我有一个现有的项目和 SQL 数据库 其中包含一个用户表 我们称之为 MyOldUsersTable 和带有 PK FK 关系的附加表 地址 电话 职位等 注意 该数据库不使用成员身份或身份 它是从另一个项目中提取的数据库 MyOldUse
  • EF6 Code First 支持表值函数吗?

    是否可以在 EF6 Code First 中调用 TVF 我首先使用 EF6 数据库启动了一个新项目 EF 能够将 TVF 导入到模型中并调用它就好了 但是 对于我一直在处理的没有 RI 的大型只读数据库 更新模型变得非常耗时并且存在问题
  • Automapper实体框架外键为空

    我正在尝试使用实体框架更新数据库 我使用自动映射器将实体映射到视图模型 并以相同的方式将其映射回来 HttpPost ValidateAntiForgeryToken public ActionResult Edit FromJson My
  • 每个数据库多个/单个 *.edmx 文件

    我有一个通过 ADO net 数据服务与数据库交互的项目 数据库很大 近 150 个具有依赖关系的表 该项目几年前开始 当时使用的是数据集 现在我们正在转向实体模型关系 由于我们添加了更多需要使用的表 该模型正在不断增长 这是管理这一切的正
  • linq2sql,存储库模式 - 如何从两个或多个表查询数据?

    我使用存储库模式 和 linq2sql 作为数据访问 并拥有例如 ProductsRep 和 CustomersRep 在非常简单的场景中 数据库有两个表 产品 产品 ID 客户 ID 产品名称 日期 和顾客 客户 ID 名字 姓氏 每个存
  • 如何在 EF Core 2.1 中定义外键关系

    我的 DAL 使用 EF Core 2 1 这就是我的模型的样子 一名用户只能拥有一种角色 Role entity kind of master public class Role public int RoleId get set pub
  • 选择里面的 Include in EF Core

    我有一个如下所示的实体 为简洁起见 部分删除 它包括许多其他属性 public class Tender Key DatabaseGenerated DatabaseGeneratedOption Identity public int I
  • 播种多对多数据

    您好 我正在尝试为我的项目创建一些种子 但我在将多对多关系数据播种到数据库时遇到问题 My database看起来像这样 in 教师技能 教师ID and Skill ID当然是他们的表的外键 My seeder看起来像这样 protect
  • 分页错误:“跳过”方法仅支持 LINQ to Entities 中的排序输入。必须在方法“Skip”之前调用方法“OrderBy”

    我正在索引页上的 MVC 中进行分页 在这一行我收到错误 return View employee ToPagedList Page 1 3 这是索引方法 public ActionResult Index string searchBy
  • 为什么 EF 5.0 在编译为 sql 时不支持此 EF 4.x LINQ 语法?

    我有一些代码最近从 EF 4 2 升级到 EF 5 0 实际上是 EF 4 4 因为我在 Net 4 0 上运行 我发现我必须更改查询的语法 我很好奇为什么 让我从问题开始 我有一个由客户端定期填充的事件日志表 对于每个事件日志 都会在报告
  • 无法使用 Ninject 将依赖项注入到从 Angular 服务调用的 ASP.NET Web API 控制器中

    我将 Ninject 与 ASP NET MVC 4 一起使用 我正在使用存储库 并希望进行构造函数注入以将存储库传递给其中一个控制器 这是实现 StatTracker 接口的上下文对象 EntityFramework public cla
  • 简单的 Linq 查询对同一个表有重复的连接?

    来自 Julia Lerman 的新实体框架书中的示例 我有一个包含两个表的数据库 联系人和地址 Contact 表有一个 ContactID int 以及名字 姓氏等 Address 表有一个 ContactID 以及城市 州 邮政编码等
  • Entity Framework 6(代码优先)实体版本控制和审计

    我正在考虑将 Entity Framework 6 1 1 与 SQL Server 2008 R2 一起使用 目前 我正在使用代码优先的 EF 功能创建模型和数据库 我的基本用例是创建一个特定实体的所有更改的日志 ID是关键栏 以帮助审核

随机推荐

  • 通过互联网传输数据的最简单方法,Python

    我有两台电脑 都连接到互联网 我想在它们之间传输一些基本数据 字符串 整数 浮点数 我是网络新手 所以我正在寻找最简单的方法来做到这一点 我需要哪些模块来做到这一点 两个系统都将运行 Windows 7 只要它不是异步的 同时发送和接收 您
  • VBscript 的递归问题

    我正在尝试在 vbscript 中实现一些递归 Function largest prime factor ByVal num For i 2 to num 2 If num mod i 0 Then this number is not
  • 如何获取特定用户的 Windows“特殊文件夹”路径?

    在服务内部 确定特定用户的特殊文件夹路径 例如 我的文档 的最佳方法是什么 SHGetFolderPath允许您传递令牌 因此我假设有某种方法可以模拟您感兴趣的文件夹的用户 有没有办法仅根据用户名来执行此操作 如果没有 用户帐户所需的最少信
  • 多行“ReplacementSpan”绘图问题

    只要文本不太长 我的自定义替换跨度就可以工作 但一旦文本长于一行 跨度绘图就会完全崩溃 我的理解是draw 在这种情况下被调用两次导致跨度绘制两次 无法区分第二个绘制调用和第一个绘制调用 从而使您可以控制绘制内容和绘制位置 start an
  • 如何使用 PlayFramework 压缩 html

    为了提高 Scala 表单的可读性 我经常使用缩进和换行 但是 当我在 play 应用程序启动并运行时验证 HTML 时 我看到很多空格和不必要的换行符 有什么理由压缩此 HTML 而不 使我的 scala 模板不可读 Thanks 正如另
  • 无法找到 Android SDK

    我已经有了安卓工作室 https en wikipedia org wiki Android Studio并安装了 Android SDK 后来我添加了 Flutter 和 Flutter SDK 这是我的问题 当我跑步时 flutter
  • 从最新的 rss 中排序日期

    我应该如何对日期进行排序 最新的在顶部 目前 日期尚未排序 下面是我的 JSFiddle http jsfiddle net qoLg6dnu http jsfiddle net qoLg6dnu document ready functi
  • android api与谷歌地图显示网格

    我正在创建一个使用谷歌地图 API v2 的 Android 应用程序 我相信我已经按照谷歌教程所述完成了所有操作 但我仍然只得到谷歌地图网格 没有地图 我使用 keystore debug 的 SHA1 创建了一个调试密钥 以下是我的设置
  • 如何编译加载到字符串中的erlang代码?

    我有一个生成的字符串 其中包含 erlang 模块的代码 有没有办法直接从字符串编译生成的模块 或者有没有办法将字符串转换为所需的格式compile forms 1 或者我必须先将其保存到临时文件中 然后使用compile file 1 或
  • fork() 中的写时复制如何处理多个 fork?

    根据维基百科 这可能是错误的 当发出 fork 系统调用时 会创建与父进程对应的所有页面的副本 并由操作系统为子进程加载到单独的内存位置 但在某些情况下不需要这样做 考虑当子进程执行 exec 系统调用 用于执行 C 程序中的任何可执行文件
  • 无法在 Next.js 13 和 Sanity v3 中使用 React 语法荧光笔

    您好 我的项目在使用 Sanity v3 和 React Syntax Highlighter 时遇到问题 当我使用Refactor用于在浏览器中显示我的代码的库 它可以通过查看教程来工作理智输入代码 https www sanity io
  • Tinymce - 插入 html 代码

    如果有人可以帮助我解决这个问题 我将不胜感激 我已经尝试解决了几天 但没有成功 我制作了将图像插入代码的自定义按钮 这是文本版本 a href Insert Image a 问题是我不允许使用引号 所以我必须使用 alt Some valu
  • 为什么字节码可能比本机代码运行得更快[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Java:为什么 NullPointerExceptions 不称为 NullReferenceExceptions?

    这是一个疏忽吗 还是跟JVM有关 Java 确实有指针 不能对其执行指针算术的指针 来自尊者JLS http docs oracle com javase specs jls se7 html jls 4 html jls 4 1 Java
  • 如何使用 ffmpeg 删除所有元数据?

    我有输入文件 infile mp3该文件包含元数据 艺术家 流派等 我尝试删除所有元数据以输出 wav file 是的 我找到了选项 地图元数据 1 但输出出乎我意料 ffmpeg i infile mp3 acodec pcm s16le
  • SQLite数据库最大存储容量

    SQLite 数据库中最多可以存储多少条记录 有什么限制吗 如果数据超出此限制 会给出什么类型的错误 整个系统会失败 还是会发生什么 基于this http developer android com guide topics data d
  • PhpStorm LESS 观察程序配置

    我正在使用 PhpStorm 8 处理一些 LESS 文件 variables less导入自styles less 当我保存时variables less only a variables css正在制作中 如何将观察者配置为仅转译sty
  • 是否有提交空选择多个的标准客户端行为?

    http www w3 org TR html401 interact forms html edef SELECT http www w3 org TR html401 interact forms html edef SELECT 不指
  • 使用 java 中的 scala.collection.immutable.Set 的示例

    有熟悉 Scala 的人知道我如何使用scala collection immutable Set http www scala lang org docu files api scala collection immutable Set
  • 实体框架 6 代码优先 - 存储库实现是一个好的实现吗?

    我即将使用存储库和工作单元实现 Entity Framework 6 设计 周围有很多文章 我不确定最好的建议是什么 例如 我真的很喜欢这里实现的模式 出于文章中建议的原因here http codefizzle wordpress com