【问题标题】:How to load business objects inherited from data layer (new answers are welcomed)如何加载从数据层继承的业务对象(欢迎新答案)
【发布时间】:2012-06-06 10:51:58
【问题描述】:

我的应用中有一个数据层和业务层。
在数据层中,我使用实体框架将数据库表作为对象导入。
例如,其中之一是 Unit 表。
现在在业务层我想向数据层单元添加一些方法,所以我有这个类:

namespace Business.Entity
{
    public class Unit : Data.Unit 
    {
     //Some business affairs here
    } 
}

为了在 UI 中加载单元,我在业务层创建了一个存储库:

    public static IEnumerable<Data.Unit> LoadUnits()
    {
        return from entity in StaticDataContext.Units select entity;
    }

到目前为止一切都很好。

但我想在 UI 中加载 Business.Unit 列表,所以我写了这个:

    public static IEnumerable<Business.Entity.Unit> LoadUnits()
    {
        var result = (from entity in StaticDataContext.Units
                      select entity).ToList().Cast<Business.Entity.Unit>();
        return result;
    }

它编译得很好,但是在将它绑定到网格时出现此运行时错误:

InvalidCastException: Unable to cast object of type 'Data.Unit' to type 'Business.Entity.Unit'

谁能说一下如何安排类才能在 UI 中加载业务类?

谢谢

【问题讨论】:

    标签: asp.net entity-framework-4 casting layer n-tier-architecture


    【解决方案1】:

    您不能直接将父对象转换为子对象。您的问题的可能解决方案:

    1. Business.Entity.Unit 类中创建一个接受Data.Unit 作为参数并分配所有必要属性的构造函数,例如:

      namespace Business.Entity
      {
          public class Unit : Data.Unit 
          {
              public Unit(Data.Unit parent)
              {
                  // Assign proprties here
              }
              //Some business affairs here
          } 
      }
      

      之后你可以这样做:

      public static IEnumerable<Business.Entity.Unit> LoadUnits()
      {
          var result = (from entity in StaticDataContext.Units
                        select new Business.Entity.Unit(entity)).ToList().Cast<Business.Entity.Unit>();
          return result;
      }
      
    2. 重写 Business.Entity.Unit 类,使其不继承 Data.Unit,但接受 Data.Unit 实体作为构造函数参数,将其聚合(存储在本地私有成员中)并将包装器属性和函数呈现给对其进行操作

    3. 完全删除您的Business.Entity.Unit 类并将所有其他方法实现为extension methods

    我会投票给第三个,因为恕我直言,它使代码更简洁,并且没有引入和管理其他实体的开销。

    【讨论】:

    • 扩展方法是个好主意。但我想严格到多层应用程序学科。让我们看看谁有其他解决方案。
    • 而且通过逃避继承,我将失去数据层对象的导航功能。
    • 如果您决定避免继承,那么无论如何您都可以使用适当的包装器围绕聚合对象的原始属性公开导航属性。可能还有解决方案 4)使用存储库模式并将您的业务逻辑移动到适当存储库类的静态方法。
    【解决方案2】:

    尝试以下方法,返回您的类 Business.Entity.Unit 对象列表,而不是强制转换为另一个类。

    public static IEnumerable<Business.Entity.Unit> LoadUnits()
            {
                var result = (from entity in StaticDataContext.Units
                              select new Business.Entity.Unit { 
                              ///set properties of this class as 
                              Id = entity.ID, .. son  
                              }).ToList();
                return result;
            }
    

    我建议你阅读 ScottGu 在Code-First Development with Entity Framework 4 上的文章。

    【讨论】:

    • 它工作得很好,但它是否给了我 EntityFramework 提供给我们的对象的导航?我的意思是这样我没有例如 Unit.Instruments 。另一个问题是,通过这种方法,我必须将所有对象字段数据从数据传输到业务,这非常耗时。
    猜你喜欢
    • 2013-11-15
    • 2021-03-25
    • 2014-09-04
    • 1970-01-01
    • 2011-04-12
    • 2012-04-03
    • 1970-01-01
    • 2022-11-24
    • 2010-10-18
    相关资源
    最近更新 更多