【问题标题】:Entity Framework POCO Entities in multi layer web application多层 Web 应用程序中的实体框架 POCO 实体
【发布时间】:2024-01-18 06:02:01
【问题描述】:

我是 EF4 的新手,之前没有任何经验。所以,如果这是一个非常简单的问题,请耐心等待。 我在 BOL 中有我的 POCO 实体(.tt 文件),在 DAL 中有 .edmx 文件(EDM),在表示层中有我的 webapp。所有的业务逻辑都进入 BLL 层。 以下是参考资料:

UI->BLL-DAL-BOL
BLL->DAL-BOL
DAL->BOL
BOL->不是我的项目。

1-我对层区分的理解正确吗?我在正确的方向吗? 2- 如何将 ASP.NET 成员资格提供程序与实体一起使用。我是否也应该实现成员资格、持久性无知并将 sql server 中的所有用户表映射到实体?

2- 如何添加自定义验证?我不是指最大长度或有效电子邮件...,我指的是访问级别。例如,我希望某些用户能够修改我网站中的一个字段(比如 productprice)。我应该在哪里使用 User.IsInRole 方法? BLL 没有对用户信息的任何引用。我应该向 BLL 传递一些参数(例如“bool CanChangePrice”)以阐明访问级别吗?

【问题讨论】:

    标签: asp.net entity-framework poco n-tier-architecture


    【解决方案1】:

    1- 你对层次的区分对我来说似乎是正确的。 我不会在 UI 中引用 DAL,因为在我的项目中,我更喜欢只有中间层访问 DAL。但这并没有错。 所以你的方向似乎是正确的。

    2- 据我所知,没有可以与 EF 一起使用的 MembershipProvider。
    所以在我们使用 Membership 的项目中,我们是这样做的:

    • 使用aspnet_regsql.exe 创建了表
    • 配置Web.Config使用SqlMembershiptProvider
    • 在 web.config 中添加了另一个连接字符串(一个用于 Membership,一个用于 EF)
    • 使用所有表构建 EDMX 文件,包括 Membership 表。

    在代码中,UserManager/RoleManager(BLL 或 DAL,取决于您的架构)使用标准成员资格方法获取信息。并且始终使用 Membership 对象,而不是 EF 对象。所以实际上用户/角色管理部分与EF是分开的。

    我们仅在您的自定义表和成员表之间存在链接时使用 aspnet_* EF 实体(例如,当您希望将其中一个表与 aspnet_Users 表链接以保留对插入数据的用户)。

    3- 对于正确的管理,我会使用 BLL RightManager,它允许 UI 知道用户是否可以更改字段(因此您可以禁用它或阻止输入),并在您的验证方法。
    在我的项目中,我使用了Right 表,并将权限与角色相关联。在RightManager 中提供RequestRight(Right) 方法。
    如果您的权限管理太简单而无法创建表,只需在 RightManager 中使用 User.IsInRole()(所以我会在 BLL 中使用它)。
    如果验证方法是“基本”,我会将验证方法放置在 UI 中,如果它包含更复杂的规则(例如涉及 DAL 访问),我会将其放置在 BLL 中。

    【讨论】:

    • 如果您不在 UI 中引用 dal,您如何访问 edmx 上下文?在 BLL 中使用存储库模式并从那里访问上下文是个好主意吗?
    • 在我的架构中,只有 DAL 应该访问上下文...每个数据库操作都由 DAL 执行。我在 DAL 中有一些助手来执行附加/分离操作(尽管我同意这不是必需的,但这只是为了保持层之间的干净分离)。我所做的是一个 ContextManager(一个 Singleton),它管理上下文并公开一个“上下文”成员。几乎每个 DAL 方法都以“var ctx = ContextManager.Instance.Context”开头。我不熟悉存储库模式,但这似乎是个好主意,但为什么在 BLL 中?上下文是一个 DAL 对象,不是吗?
    • 在 BLL 中使用存储库模式允许我们创建从 DAL 返回的对象和列表。但是考虑到您的架构(只有 DAL 应该可以访问上下文),那么该模式应该在 DAL 中实现。我不得不承认你的方法是一种分离层的干净方法。
    【解决方案2】:

    Wow Kamyar,这个问题只包含了几个问题;-) 我不确定我是否会涵盖所有可能的领域,但这里是。

    项目结构
    - 通常您的项目结构是正确的,并且您拥有的参考资料是正确的。有些人可能会争辩说你想把你的关注点分开一点并打破一些参考,但我个人认为你的结构是可行的。

    • 实际上,我倾向于将我的 EDXM 和 POCO 保留在同一个项目中。我只有一个包含 EDXM 和 Model.Context.tt 的 Entities 文件夹,一个用于 Model.tt 和我的 Virtual POCO(如下)的 POCO 文件夹,以及一个用于我的存储库和工作单元的 Repository 文件夹。

      李>
    • 我还创建了一个名为 VirtualPOCOs 的文件,它是绑定到 T4 生成的 POCO 的部分类。我的设计往往与数据库结构紧密相关。 VirtualPOCO 给了我一点灵活性,让我在那些一次性的情况下偏离 DB 设计。这里没有太多内容,只是每个项目似乎都有的几个非常具体的需求。

    • 您可能还需要考虑存储库、表数据网关或活动记录设置。所有这些模式都可能与工作单元相结合。有大量的设计模式,您的需求或偏好可能会将您推向其中一种。这里的重点是屏蔽上层直接访问 EF4 上下文。通过这种方式,您可以集中连接和事务管理,并确保上层仅使用 POCO 而不会意外保留 linq-to-sql 对象。

    会员提供者
    MembershipProvider 和 EF 之间肯定存在分歧。但是,您可以下载 SQLMembershipProvider 的源代码并将其转换为使用 EF。我实际上做了这个转换。该文件大约有 1500 行长,但没有大量的 ADO 代码。

    你没有问,但我想我应该解决的是,你是否想使用会员提供者。如果您正在进行基本的会员管理和角色,那么会员、角色和个人资料提供程序可以为您节省大量时间。如需深入了解这些功能,请查看 4GuysFromRolla (http://www.4guysfromrolla.com/articles/120705-1.aspx) 上的系列。

    如果您的需求更复杂,恕我直言,会员提供商很快就会崩溃。例如,当用户注册您的站点时,您必须立即在几个不同的表中创建行。嗯,membership provider是通过webconfig注册的,使用membership provider接口。它只接受 create 函数中的某些字段。那么男孩该怎么办呢?好吧,你可以在你的控制器中打开一个更大规模的事务,运行会员提供者添加用户功能,运行你自己的MyCustomUserStuff(),然后提交事务。我觉得这不吸引人的两个原因是,我现在有事务代码渗入我的调用堆栈,如果我需要做的只是添加一些额外的字段,我现在已经不必要地加倍了我的数据库调用。

    我想我只是发现会员提供程序非常有限,一旦进入并创建了我自己的自定义会员提供程序,使用 MS 模型的好处很快就消失了。

    验证
    我认为这里的答案是响亮的——这取决于。你的权限是静态的吗?即“SiteManagers”组中的那些可以在整个站点上进行编辑?还是您的权限更加细化?这意味着 SiteManager 可以访问分布在这 22 个表中的这 75 个字段,还是更多基于表的字段?此外,权限的可变性如何?您的站点管理员是否需要能够频繁地打开/关闭或关闭对不同表中的各个字段的访问?

    我想我需要更多地了解您对特定答案的要求。请记住,您的权限越细,客户端就越容易理解和管理所有权限。

    另外,您使用的是什么后端?许多 DBA 面临这些决定。在那个世界中,一个常用的策略是创建一系列视图,其中每个视图都显示用户拥有的列。例如,EmployeesHR 视图将仅公开 HR 人员有权访问的那些列,而 EmployeeDirectory 将仅公开目录有权访问的那些字段。然后 HR 用户将获得 HR 视图的权限,但不会基础表。只是一个想法。

    无论如何,希望这会有所帮助。

    【讨论】:

    • 这绝对有很大帮助。谢谢你。
    【解决方案3】:

    关于 EF 和会员资格 据我所知,您不需要使用任何数据库提供程序而不是会员提供程序 但如果您愿意,您可以在 EF 中映射成员资格表并创建其他方法 共同提供者

    【讨论】:

      最近更新 更多