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

本文关键字:对象 转换 视图 业务 POCO 请求 MVC 框架 模型 数据类型 实体 | 更新日期: 2023-09-27 18:16:49

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

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

查看项目引用控制器和模式项目。控制器项目引用模型项目

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

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

例如,在View命名空间中,我有下面的object:

          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分别由model中的EntityA和View中的EntityA实现。因此,一旦我从视图中从模型中检索数据:

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

我必须将'a'对象(其类型为namspace . model . entitya)转换为视图中的等效对象:

         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属性,因此一旦获得转换对象在视图中转换:

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

我必须做另一个请求数据库获得EntityB,然后转换它,最后从视图分配到EntityA。

// 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。-正如你所看到的,我必须为每个实体都有一个转换器,因为从视图中,我不能把从数据库请求接收到的对象当作视图使用自己的实体.....显然,我必须在每个实体中实现接口,模型的实体和视图的实体。

原因是我完全隔离了模型项目,它使用自己的实体,视图也使用自己的实体。

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

所以我的问题是:有没有更好的方法来避免每次使用数据类型转换器?或者你认为这种架构是好的,因为它将模型从视图中分离出来?使用这种方法,如果你改变了视图中的实体,模型不会受到影响,因为它有自己的实体。我的问题是每次使用数据类型转换器....

任何想法?

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

不要为每个类编写自己的转换器,看看AutoMapper吧。它将为您省去大量的编码工作。

不确定这是否真的是Stack Overflow的问题(感觉太像"你对…有什么看法"),但既然你花了时间打了这么长的解释,我将呈现我的两个观点:

我觉得你的设计太复杂了。有句谚语说"解决方案的复杂性不应该超过问题的复杂性",感觉你已经做到了(如果没有对问题的具体背景知识,很难说)。为了它的价值,我发现的"模式"是SoC和复杂性之间的最佳权衡是:
  1. 数据项目。提供对数据存储的编程访问(数据库、XML等)。
  2. 域项目。提供业务逻辑/规则的实现。我也可以在这里定义我的dto。
  3. UI项目。假设您正在开发一个供用户使用的工具该项目直接提供网站、控制台或桌面应用程序,并且仅限于基本验证(所需值)

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

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

HTH .