c# - 您如何在不引用数据访问层的情况下使分层解决方案的UI项目解析EF实体

标签 c# winforms entity-framework n-tier-architecture layered

我正在使用一个WinForms应用程序,该应用程序由3层构成,每一层是一个单独的项目,如下所示:

Projects in solution

在SampleNtierDAL项目中有一个DalServices类,其定义如下:

namespace SampleNtierDAL
{
    public class DalServices
    {
        public static List<Employee> GetEmployees()
        {
            List<Employee> employeeList = null;
            using (SampleNtierEntities aSampleNtierEntitiesDbContext = new SampleNtierEntities())
            {
                employeeList = (from emp in aSampleNtierEntitiesDbContext.Employees select emp).ToList();
            }
            return employeeList;
        }
    }
}


在SampleNtierBLL项目中,有一个BllServices类,其定义如下:

namespace SampleNtierBLL
{
    public class BllSerices
    {
        public static List<Employee> GetEmployees()
        {
            return DalServices.GetEmployees();
        }
    }
}


SampleNtierUI项目有一个WinForm按钮事件,该事件应要求BllServices获取雇员列表,如下所示:

namespace SampleNtierUI
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnGetListOfEmployees_Click(object sender, EventArgs e)
        {
            List<Employee> anEmployeeList = BllSerices.GetEmployees();
        }
    }
}


这里的问题是WinForm无法看到由实体框架6创建的名为“雇员”的实体模型。SampleNtierBLL项目类BllServices看到了该类,因为它引用了SampleNtierDAL并在顶部具有use语句来进行解析Employee类。我曾考虑过在WinForm中添加类似的引用来解决Employee类,但是我在其他文章中看到您不应该对数据访问层进行引用,但是此类文章并未显示如何解决我遇到的这个问题。
有人可以告诉我如何在不引用实体框架生成名为Employee的实体的数据访问层的情况下,如何获得UI(WinForm)识别的Entity模型(Employee类)吗?
提前致谢。

更新至我的帖子2015/11/5 5:13

在对该过程进行了更多测试之后,我在2015年11月5日下午14:14中添加了该过程,我发现它实际上在带有.NET 4.5.2的Visual Studio 2015上也可以正常工作。

更新至我的文章11/5/2015 3:14 pm:

感谢Reza为提供响应信息所做的所有工作。正如所记录的那样,我无法使您的解决方案与Visual Studio 2013或Visual Studio 2015一起使用。但是,我确实在Julie Lerman的Pluralsight.com上找到了一个提供解决方案的互联网视频。她的解决方案没有提到使用NuGet管理部分(您已经这样做了),因此我将其添加到组合中并最终完成了一个工作项目。朱莉·勒曼(Julie Lerman)的视频标题为:

“从EDMX分离生成的域类”,位于以下位置:

http://www.pluralsight.com/training/player?course=entity-framework5-getting-started&author=julie-lerman&name=ef5-m6-solutions&clip=2&mode=live

通过将您的过程的一部分与她的过程结合在一起,我完成了以下步骤,这些步骤对我适用于Visual Studio 2013,但不适用于Visual Studio 2015。

我的样本最初有以下项目:


SampleNtierDAL
SampleNtierBLL
SampleNtierUI


在此项目列表中,我添加了一个名为SampleNtierModels的第四个项目,因此该列表如下所示:


SampleNtierDAL
SampleNtierBLL
SampleNtierUI
SampleNtier模型


遵循的步骤:
1)设置项目参考如下:


SampleNtierBLL引用SampleNtierDAL和SampleNtierModels
SampleNtierDAL参考SampleNtierModels
SampleNtierDAL没有引用任何项目
SampleNtierUI引用SampleNtierBLL和SampleNtierModels


2)接下来,启动File Explorer程序(用于浏览文件系统文件的工具),并将ModelEmployee.tt文件从DAL项目文件文件夹移动到models文件文件夹。

3)使用Visual Studio解决方案资源管理器,转到SampleNtierModels项目,右键单击并选择“添加现有项”。在对话框中,选择“所有文件”以查看ModelEmployee.tt文件,然后选择它以将其添加到项目中(不要选择链接文件)。

4)接下来,选择SampleNtierDAL项目,然后右键单击ModelEmployee.tt文件并将其删除,这也会自动删除其下的所有.cs文件。完成后,ModelEmployee.tt节点应消失。

5)选择SampleNtierModels项目,然后单击ModelEmployee.tt节点,这将在编辑器中打开MoadelEmployee.tt文件。内容的顶部是const字符串inputFile的关联。设置此字符串以找到ModelEmployee.edmx文件,如下所示:

const string inputFile = @"..\SampleNiter\SampleNtierDAL\ModelEmployee.edmx


5)接下来,选择SampleNtierDAL项目并打开ModelEmployee.Context.tt文件,并向下滚动引用使用子句的部分,并添加SampleNtierModels命名空间,如下所示:

if (container.FunctionImports.Any())
{
#>
using System.Data.Entity.Core.Objects;
using System.Linq;
using SampleNtierModels;
<#
}


7)选择SampleNtierBLL项目,打开BLLServices.cs文件并添加以下using语句:

using SampleNtierModels;
using SampleNtierDAL;


8)选择SampleNtierDAL项目,打开DalServices.cs文件并添加以下using语句:

using SampleNtierModels;


7)选择SampleNtierUI项目,打开Form1.cs文件并添加以下using语句:

using SampleNtierModels;
using SampleNtierBLL


8)单击菜单栏中的工具,然后单击NuGet软件包管理器,然后


选择已安装的软件包
搜索实体框架
选择显示的EntityFramework软件包,然后单击其
“管理”按钮
在列表框中,确保选择了以下内容:
SampleNtierBLL,SampleNtierDAL,SamleNtierUI


9)选择SampleNtierDAL项目,右键单击ModelEmployee.Context.tt节点,然后选择“运行自定义工具”。

10)选择SampleNtierModels项目,右键单击ModelEmployee.tt节点,然后选择“运行自定义工具”。

11)将SampleNtierDAL项目中App.Config文件的全部内容复制到SampleNtierUI项目中的App.Config文件中。

下面的示例图片显示了项目的最终外观,以及示例调试会话,其中显示了从实体框架返回的3行数据,这些数据行从DAL到BLL,最后是UI。 Winform UI也显示不需要引用DAL。

现在已解决了此问题,因此再次感谢Reza帮助解决此问题。我给Juile留下了一条消息,要求更新此处的流程,其中包括Visual Studio 2015。

enter image description here

最佳答案

简短答案

您应该将模型放置在与DAL不同的项目中,以使模型对User Interface (UI)项目可见,而无需引用Data Access Layer (DAL)项目。并且您的所有项目都应参考您的模型项目。

使用Database/Model First方法执行此操作的关键点是在模型项目中“添加现有项”,然后选择模型的.tt文件,然后从对话框中“添加”按钮的下拉菜单中选择Add as Link

分步指南创建分层解决方案

要使用实体框架将模型放入单独的项目中,请遵循以下步骤:

建立专案


创建一个项目并将其命名为例如Sample.DAL
创建另一个项目并将其命名为Sample.Models
创建另一个项目并将其命名为Sample.BLL
创建另一个项目并将其命名为Sample.UI


配置参考

使用以下规则添加对项目的引用:


Sample.UI依赖于Sample.BLLSample.Models
Sample.BLL依赖于Sample.DALSample.Models
Sample.DAL依赖于Sample.Models
Sample.Models不依赖于其他项目


配置样本


将您的SampleDB.edmx添加到Sample.DAL项目
展开Sample.edmx节点,然后展开SampleDB.tt节点,并删除SampleDB.tt下的所有.cs文件。
SampleDB.tt的属性中,清除CustomTool


配置样本模型


Add Existing ItemSample.Models,然后在对话框中,转到Sample.DAL文件夹,然后从组合框中选择All files,然后选择SampleDB.tt,然后单击“添加”按钮的下拉菜单,然后从菜单中选择Add As Link
选择SampleDB.tt,然后在属性中将CustomToolNamespace设置为Sample.DAL
右键单击SampleDB.ttRun Custom Tool


管理Nuget软件包


右键单击解决方案,然后选择Manage Nuget Packages for Solution并选择已安装的软件包,选择Entity Framework并单击“管理”。选择Sample.DALSample.BLLSample.UI


配置Sample.BusinessLogic

使用以下代码创建一个YourEntityBusinessLogic类:

public class YourEntityBusinessLogic
{
    public List<YourEntity> GetAll()
    {
        var context = new YourDBContext();
        return context.YourEntities.ToList();
    }
} 


注意不要在公共属性中或作为方法和构造函数的输入参数或返回值公开YourDBContext。

配置Sample.UI


app.configSample.DAL文件复制连接字符串,并粘贴到app.config标记之前的Sample.UI<entityframework>
创建一个Form并将其设置为启动,并在FormLoad或所需的任何位置以测试方式运行此代码:




//Shows count of records in your table
var business = new YourEntityBusinessLogic();
MessageBox.Show(business.GetAll().Count().ToString());


解决方案结构

这是解决方案的结构,如您所见,上下文位于Sample.DAL中,而模型位于Sample.Models中。

因此,您无需在DAL项目中添加对UI的引用。

enter image description here

关于c# - 您如何在不引用数据访问层的情况下使分层解决方案的UI项目解析EF实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33527484/

相关文章:

c# - Page_load 中的 Post 方法数据

c# - 需要为最大日期值构建表达式树

entity-framework - 在不删除数据的情况下更新数据库架构?

entity-framework - 如何首先在 Entity Framework 4 代码中映射复合主键?

c# - 使用 DrawString 方法复制标签

c# - Azure 移动服务登录数据库和 "master"用户时出现错误

c# - 层次结构不会在 View 中更新

c# - 禁用窗体双击时的最大化/最小化

c# - 您应该如何诊断错误 SEHException - 外部组件抛出异常

c# - Entity Framework 代码优先数据库不更新