【问题标题】:MVC + POCO + Entity Framework, Passing Object between layersMVC + POCO + Entity Framework,层间传递对象
【发布时间】:2012-03-25 10:48:31
【问题描述】:

我正在尝试 MVC 2、ADO.NET EF 和 POCO。我已经使用 POCO 生成器在单独的库中生成了我的实体类。这些 POCO 实体用作 ViewPages(不确定这是否是正确的设计方法,还是我需要单独的 ViewModels 类?)

现在,如果我需要添加一个员工对象(与部门主管相关)的简单场景,那么在层之间传输这些对象的推荐方法应该是什么。

应用程序的分层结构有点像这样:

我已经想到了各种替代方案:

我在员工控制器中有一个名为 AddEmployee() 的方法,它接受 FormCollection 作为参数。在表单集合中,我得到发布的数据,例如员工姓名、年龄、工资等以及所选部门的 ID。

1.) 一种方法是我可以创建另一个 DTO,例如 EmployeeDepartment DTO,它将用于按原样映射来自 FormCollection 的值。然后我可以在经理层打破它们并使用它们来创建实体对象,即员工对象,并通过类似于以下的查询来引用部门:

e.Department =  Department.where(i => i.deptId == empDepDto.dept_id).first()

我不是这方面的忠实拥护者,并且觉得每次涉及到关系时,我都必须添加一个 DTO,然后将其映射到我的实体类。

2.) 第二个可能是最糟糕的,即将每个对象作为参数传递,然后将它们耦合到管理层。

3.) 按原样使用 POCO,在控制器层创建 Employee 对象和 Deparment 对象并传递 POCO 对象

public void AddEmployee(FormCollection formCollection)
{
    Department d = new Deparmtent; d.id = ""; //based on the dropdown value
    d.name="" //based on the dropdown selected text;

    Employee e = new Employee; e.Name. e. sal....

    e.Department = d;

    EmployeeManager.AddEmployee(e);
}

但我认为在经理层,我仍然需要使用 LINQ 重新创建对部门的引用,这又是重复的,似乎不是一个干净的解决方案。

有没有更好的方法来处理这个问题?寻找建议和最佳做法。

【问题讨论】:

    标签: asp.net .net asp.net-mvc asp.net-mvc-2 poco


    【解决方案1】:

    首先,您有什么理由不使用 MVC 版本 3?没有重大的重大变化,所以不妨升级一下?

    其次,是否有理由使用 FormCollection 而不是强类型模型绑定?只需更改您的视图以使用强类型 HTML 帮助程序(如 <%: Html.TextBoxFor(m => m.Property) %>),或确保 name 属性与属性名称匹配,并让您的控制器接收类型,然后模型绑定将完成其余工作。有很多教程展示了这一点,还有解释它的文章。模型绑定将与名称/值集合一起使用,例如作为表单发布的集合,或针对 JSON 数据,或者您可以查找/编写自定义模型绑定器,以针对您想要的任何古怪的序列化协议工作。

    在传递 Entity Framework 将存储的实际实体类型时需要注意的一点是,在更新现有对象或使用对现有对象的外键引用时必须小心 - 所有对象都必须附加到正确的实体框架上下文。为了实现这一点,您经常会看到控制器接收到的对象将其属性复制到从上下文中新检索的实体中,无论是手动还是通过某种对象映射器。

    【讨论】:

    • 没有不选择 MVC 3 的具体原因。我希望无论版本如何,问题都将保持不变。我没有尝试过模型绑定,但绝对可以尝试使用它,看看它有什么帮助。
    【解决方案2】:

    创建一个名为“BusinessObjects”或“Model”的单独项目,其中包含您的 POCO。然后为 MVC 使用强类型模型绑定,您将被设置。

    方法签名看起来像这样:

    // In your Controller
    public void AddEmployee(Employee newObject)
    {
          YourDataContext dc = new YourDataContext();
          dc.Employees.Add(newObject);
          dc.SaveChanges();
    
    }
    

    【讨论】:

    • :我不认为这是一个干净的解决方案。你的控制器应该是完全无知的。您已经在控制器本身中使用了实体上下文。
    • @Kunal,我认为你错过了重点。欢迎您在您认为合适的任何层进行持久性,但是传递您的 poco 是您应该做的。使用强类型视图并为控制器操作使用模型绑定,这样你的状态会更好。
    • 忽略持久性,您可以将其移出。要看的重点是强类型输入参数——它是实际的模型绑定。但是,应该有一个 ActionResult 类型或其后代之一的返回值。您通常只通过 HttpPost 属性指定 post,并返回重定向,即“post-redirect-get”模式。
    • @Kunal 听起来您可以控制应用程序的所有层。如果是这样,您选择编写多层应用程序是否有特定的商业原因?青色的回答是我推荐的。引入层很容易使您编写的代码量翻两番,并增加出现错误的可能性。选择满足您需求的最简单的架构。您可以随时对其进行重构。
    猜你喜欢
    • 2011-03-31
    • 2011-07-26
    • 2013-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-12
    • 1970-01-01
    相关资源
    最近更新 更多