1

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

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

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

在模型和视图之间还有另一个项目,比如说项目 MV,它包含一个接口和一些转换器(我将在下面解释)。模型项目引用 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由model中的EntityA和View中的EntityA实现。因此,一旦我从视图中从模型中检索数据:

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

我必须将“a”对象(类型为 Namespace.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属性,因此一旦获得转换后的对象aConverted in风景:

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

我必须对数据库执行另一个请求以获取 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.- 如您所见,我必须为每个实体都有一个转换器,因为从视图中我无法处理从数据库请求接收到的对象,因为视图使用了自己的实体.....显然我必须在每个实体,模型实体中的实体和视图实体中的实体。

造成这种情况的原因是我已经完全隔离了模型项目,它使用自己的实体,视图也使用自己的。

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

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

有任何想法吗?

4

2 回答 2

3

与其为每个类编写自己的转换器,不如看看AutoMapper。它将使您免于大量编码。

于 2013-06-03T21:15:12.400 回答
1

不确定这是否真的是 Stack Overflow 的问题(感觉太像“你对……有什么看法”),但既然你花时间打了这么长的解释,我会付两分钱:

我认为你的设计过于复杂了。有一句格言是“解决方案的复杂性不应超过问题的复杂性”,感觉就像你已经做到了(如果没有对问题的具体背景知识,很难说)。对于它的价值,我发现在 SoC 和复杂性之间进行最佳权衡的“模式”是这样的:

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

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

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

HTH。

于 2013-06-03T20:59:46.577 回答