1

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

解决方案中的项目

在 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();
        }
    }
}

Te 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 无法看到由 Entity Frameworks 6 创建的名为“Employee”的实体模型。 SampleNtierBLL 项目类 BllServices 看到该类是因为它引用了 SampleNtierDAL 并在顶部有一个 use 语句来解决员工类。我曾考虑在 WinForm 中添加类似的引用来解析 Employee 类,但我在其他文章中看到您不应该引用数据访问层,但这些文章没有显示如何解决我遇到的这个问题。
有人可以告诉我如何在不引用实体框架生成名为 Employee 的实体的数据访问层的情况下让 UI(WinForm)识别实体模型(Employee 类)吗?提前致谢。

更新到我的帖子 2015 年 11 月 5 日下午 5:13

在对我在 2015 年 11 月 5 日下午 3:14 添加的过程进行了更多测试后,我发现它实际上也适用于带有 .NET 4.5.2 的 Visual Studio 2015。

更新到我的帖子 2015 年 11 月 5 日下午 3:14:

感谢 Reza 为提供响应信息所做的所有工作。我无法使您的解决方案与 Visual Studio 2013 或 Visual Studio 2015 一起工作,因为它已记录在案。但是,我确实在 Pluralsight.com 上找到了 Julie Lerman 的一个互联网视频,它确实提供了一个解决方案。她的解决方案没有提到使用您使用的 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。

我的示例最初有以下项目:

  • 样品NtierDAL
  • 样品NtierBLL
  • SampleNtierUI

在这个项目列表中,我添加了第四个名为 SampleNtierModels 的项目,所以现在的列表如下:

  • 样品NtierDAL
  • 样品NtierBLL
  • SampleNtierUI
  • SampleNtierModels

步骤如下: 1) 设置项目引用如下:

  1. SampleNtierBLL 参考 SampleNtierDAL 和 SampleNtierModels
  2. SampleNtierDAL 参考 SampleNtierModels
  3. SampleNtierDAL 没有引用任何项目
  4. SampleNtierUI 引用 SampleNtierBLL 和 SampleNtierModels

2) 接下来,启动文件资源管理器程序(用于浏览文件系统文件的工具)并将 ModelEmployee.tt 文件从 DAL 项目文件夹移动到模型文件夹。

3) 使用 Visual Studio 解决方案资源管理器,转到 SampleNtierModels 项目,右键单击并选择 Add Existing Item。在对话框中,选择“All Files”以查看 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 文件并向下滚动引用 using 子句的部分并添加 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 包管理器

  1. 选择已安装的包
  2. 搜索实体框架
  3. 选择显示的 EntityFramework 包,然后单击其“管理”按钮
  4. 在列表框中确保选择了以下内容: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。

在此处输入图像描述

4

1 回答 1

3

简答

您应该将模型放在一个单独的项目中,而不是DAL让您的模型对项目可见,User Interface (UI)而无需引用Data Access Layer (DAL)Project。并且您的所有项目都应该引用您的模型项目。

使用Database/Model First方法执行此操作的关键点是“添加现有项目”到您的模型项目并选择.tt模型文件并Add as Link从对话框中添加按钮的下拉列表中进行选择。

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

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

创建项目

  1. 例如创建一个项目并命名它Sample.DAL
  2. 创建另一个项目并命名Sample.Models
  3. 创建另一个项目并命名Sample.BLL
  4. 创建另一个项目并命名Sample.UI

配置参考

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

  1. Sample.UI依赖于Sample.BLL并且Sample.Models
  2. Sample.BLL依赖于Sample.DAL并且Sample.Models
  3. Sample.DAL依赖于Sample.Models
  4. Sample.Models不依赖其他项目

配置示例.DAL

  1. 添加你SampleDB.edmxSample.DAL项目
  2. 展开Sample.edmx节点,展开SampleDB.tt节点,删除下所有.cs文件SampleDB.tt
  3. SampleDB.tt清除的属性中CustomTool

配置示例.模型

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

管理 Nuget 包

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

配置示例.BusinessLogic

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

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

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

配置示例.UI

  1. 将您的连接字符串从app.config文件中复制Sample.DAL并粘贴到标签之前app.configSample.UI<entityframework>

  2. 创建一个Form并将其设置为启动并将此代码作为测试FormLoad或任何您想要的地方运行:

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

解决方案结构

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

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

在此处输入图像描述

于 2015-11-04T18:47:07.160 回答