繁体   English   中英

实体框架 - MVC - 将Model中数据库请求的数据类型(POCO对象)转换为View中使用的业务对象

[英]Entity Framework - MVC - Converting data types requested from database in Model (POCO objects) into business objects used in the View

我正在使用MVC模式和实体框架4.1。 我有三个项目:模型(M),视图(V)和控制器(C)。

                         M <-------- V --------> C
                         ^                       |
                         |_______________________|

查看项目参考控制器和模式项目。 控制器项目参考模型项目。

在Model和View之间有另一个项目,比如项目MV,包含一个接口和一些转换器(我将在下面解释).Model项目引用MV。 还可以查看参考MV。 但MV是独立的,它不引用任何项目,既不是模型也不是视图。

在我拥有POCO对象(实体)的模型中,那些定义了物理数据库设计。 因为我想从视图中隔离模型,也就是说,我不希望模型依赖于视图,模型有自己的实体,视图也有自己的实体。

例如,在View命名空间中,我有以下对象:

          public class EntityA : InterfaceMV
          {
             public string Property1 { get; set; }
             public int Property2 { get; set; }
             EntityB entityB;   <--- refrences an entity in the same namespace              
          }

在模型命名空间中我有下面的对象,实际上它包含相同的属性:

         public class EntityA : InterfaceMV
         {
             public string Property1 { get; set; }
             public int Property2 { get; set; }
             EntityB entityB;  <-- foreign key to an entity in the same namespace
         }

我没有在模型和视图中共享的实体所以我的问题是从视图中我直接访问模型以使用上下文检索一些数据,所以从视图我做:

          using (DBContext context = new DBContext())
          {
              Namespace.Model.EntityA a = context.EntitiesA.Find(id);
          }

因为模型和视图使用不同的实体(尽管它们具有相同的属性和相同的名称,它们被视为不同的对象,因为它们不同于不同的命名空间),我必须将数据从模型对象转换为视图对象。 这种转换是使用我在上面评论的项目MV中包含的接口(InterfaceMV)中的转换器(接口)完成的。 InterfaceMV如下:

public interface IDataTypeConverterEntityA
{
    string Property1 {get; set;}
    int Property2 {get; set; }
}

InterfaceMV由模型中的EntityA和View中的EntityA实现。 所以一旦我从视图中检索模型中的数据:

         Namespace.Model.EntityA a = context.EntitiesA.Find(id);

我必须将'a'对象(类型为Namespace.Model.EntityA)转换为View中的等效对象:

         EntityA aConverted = DataTypeConverterEntityA.Convert<Namespace.Model.EntityA, EntityA>(a);

转换器如下所示(它在类DataTypeConverterEntityA中):

    public static Y Convert<T, Y>(T itemToConvert) 
         where T : new(), IDataTypeConverterEntityA 
         where Y : new(), IDataTypeConverterEntityA
    {
        return new Y 
                {
                    property1 = itemToConvert.property1,
                    property2 = itemToConvert.property2                        
                };
     }

基本上,我有我的POCO实体代表我的数据库中的表,我有一些业务类,我使用转换器从一个转移到另一个。

问题如下:1.-由于包含interfaceMV的项目MV既不引用模型也不引用视图,convert方法只能转换标量类型但不能转换其他类型如EntityB属性,因此一旦获得转换后的对象aConverted in风景:

// I retrieve the matching entity from the context
EntityA aConverted = DataTypeConverter.Convert<Namespace.Model.EntityA, EntityA>(a);

我必须对数据库进行antoher请求以获取EntityB,然后转换它,最后通过执行以下操作从视图分配到EntityA.entityB:

// I retrieve the matching entity from the context
Namespace.Model.EntityA a = context.EntitiesA.Find(id);
EntityA aConverted = DataTypeConverterEntityA.Convert<Namespace.Model.EntityA, EntityA>(a);

// Inject values into the entity
Namespace.Model.EntityB b = context.EntitiesB.Find(id);
EntityB bConverted = DataTypeConverterEntityB.Convert<Namespace.Model.EntityB, EntityB>(b);

aConverted.entityB = bConverted;

2.-正如你所看到的,我必须为每个实体都有一个转换器,因为从视图中我不能处理从数据库请求接收的对象,因为视图使用它自己的实体.....显然我必须实现接口每个实体,在模型的实体中,在View的实体中。

造成这种情况的原因是我完全隔离了模型项目,它正在使用它自己的entites并且视图也在使用它自己的。

也许只将实体(EntityA,EntityB,....)保存在一个地方并在Model和View之间共享它们可以解决这个问题....避免使用数据类型转换器。

所以我的问题是:有没有更好的方法来避免每次使用数据类型转换器? 或者您认为这种架构是好的,因为它将模型与View隔离开来? 使用这种方法,如果你在View中更改了实体,那么模型就不会受到影响,因为它有自己的实体。 我的问题是每次都使用数据类型转换器....

有任何想法吗?

不要为每个类编写自己的转换器,而是查看AutoMapper 它将为您节省大量编码。

不确定这是否真的是Stack Overflow的问题(感觉太像“你的意见......”),但是由于你花了很多时间来填写这么长的解释,我会渲染我的两分钱:

我认为你的设计过于复杂。 有一句格言“解决方案的复杂性不应超过问题的复杂性”,感觉就像你已经完成的那样(很难说没有特定的问题背景知识)。 对于它的价值,我发现SoC和复杂性之间最好的权衡的“模式”是这样的:

  1. 数据项目。 提供对数据存储(数据库,XML等)的编程访问。
  2. 域项目。 提供业务逻辑/规则的实现。 我也在这里定义我的DTO。
  3. UI项目。 假设您正在开发一个供用户直接使用的工具,该项目提供网站,控制台或桌面应用程序,并且仅限于基本验证(例如,提供了所需的值)。

如果我需要散列或加密例程,我倾向于将它们放在第四个项目中,但它们也可以与域项目混在一起。

根据此设计,域项目引用数据项目,UI项目引用域项目。 大部分工作发生在域项目中,数据项目通常只是数据存储的包装器,UI项目将用户请求路由到适当的域逻辑。

HTH。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM