【问题标题】:c# mapping between Domain Entity and Data Entity in Repository Pattern and unit of work projectc# 存储库模式和工作单元项目中域实体和数据实体之间的映射
【发布时间】:2016-10-16 14:11:25
【问题描述】:

我有 C# 应用程序的 SOA 层架构。我已经在业务访问层“类库项目”中定义了业务/域实体......数据访问层“类库项目”中的数据实体和服务器端 WCF 的数据合同位于 WCF 服务“类库项目”下

商业实体

namespace App.Core.Entities
{
public class Member
{
    public int MemberID { get; set; }

    public string Title { get; set; }

    public string Surname { get; set; }

    public string Forename { get; set; }

    public string MiddleName { get; set; }
}

数据实体

namespace App.DAL.Entities
{
[Table("Member")]
public class Member
{
    [Key]
    public int MemberID { get; set; }

    public string Title { get; set; }

    public string Surname { get; set; }

    public string Forename { get; set; }

    public string MiddleName { get; set; }

  }

}

WCF 数据协定

namespace App.Services.Contracts 
{
[DataContract]
public class MemberData : IIdentifiableEntity
{
    [DataMember]
    public int MemberID { get; set; }

    [DataMember]
    public string Title { get; set; }

    [DataMember]
    public string Surname { get; set; }

    [DataMember]
    public string Forename { get; set; }

    [DataMember]
    public string MiddleName { get; set; }

    int IIdentifiableEntity.EntityId
    {
      get { return MemberID; }
      set { MemberID = value; }
    }
  }
}

通用存储库

 public interface IGenericRepository<TEntity> where TEntity :class
{

    global::System.Linq.IQueryable<TEntity> GetAll();
    TEntity GetEntityByID(int id);
    void InsertEntity(TEntity obj);
    void UpdateEntity(TEntity obj);
    void DeleteEntity(int id);

}

工作单元

namespace App.Repository.UnitOfWork
{
 public class MembershipManagement_UOF:IDisposable
 {        
    protected Member_Repository _Member_Repository;  

   public Member_Repository Member_Repository
    {
        get
        {
            if (this._Member_Repository == null)
            {
                this._Member_Repository = new Member_Repository(_MembershipContext);
            }

            return _Member_Repository;
        }
    }    
  }

现在我的问题是,当我从业务项目运行代码时,它应该只与存储库对话并且只使用成员的业务实体,但它要求我在业务项目中添加来自 DAL 的引用

这是我得到错误的代码

 public IEnumerable<Member> GetAllMember()
    {
        using (var _uof = new MembershipManagement_UOF())
        {
            var entities = _uof.Member_Repository.GetAll();

            // return entities.ToList();

            return null;
        }
    }

错误

Severity    Code    Description Project File    Line    Suppression State
 Error  CS0012  The type 'Member' is defined in an assembly that is not referenced. You must add a reference to assembly 'App.DAL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.  App.CoreServices    C:\My Work\Credit Union  Application\CreditSolutionApp\App.CoreServices\CoreServices\MembershipCore\MembershipCore.cs   23  Active

【问题讨论】:

    标签: c# wcf entity-framework-6 repository-pattern soa


    【解决方案1】:

    从原始帖子中很难分辨,但我怀疑您对 IGenericRepository 接口的具体实现是从 DAL 而非 BLL(业务逻辑层)引用 Member 类。具体存储库需要使用 BLL 中的 Member 类作为其通用 TEntity 类型。具体repository类的方法需要使用DALMember类从DB加载数据,然后将那些DALMember实例映射到BLLMember实例,然后返回BLLMember实例。

    将 DAL 成员类重命名为 MemberDto 之类的名称可能有助于避免此处的混淆。所以,你可能会得到类似的结果(IGenericRepository&lt;TEntity&gt; 在你的 BLL 中,MyMemberRepo 在你的 DAL 中):

    public class MyMemberRepo : IGenericRepository<Member>
    {
        public IEnumerable<Member> GetAllMember()
        {
            // 1. Load the data from the data store into an IEnumerable<MemberDto>.
            // 2. Map the IEnumerable<MemberDto> to an IEnumerable<Member>, perhaps
            //   using something like the open source AutoMapper project.
            // 3. Return the IEnumerable<Member>.
        }
        // ... other interface implementations...
    }
    

    【讨论】:

    • 如果我使用 IGenericRepository 接口的具体实现是从 BLL(业务逻辑层)引用,那么我将如何处理 DbSet,因为它们都引用了 DAL 实体,它定义了主键、外键和表名
    • 主应用程序引用 BLL,BLL 引用 DAL,而 DAL 使用 ADO.NET 或 LINQ2SQL 或实体框架或任何您想要访问数据库的东西。由于app只引用BLL,所以只能引用IGenericRepository接口;它不能直接引用具体的存储库。因此,您需要使用反射或某种形式的控制反转 (IoC) 来实例化 IGenericRepository 接口的具体实现。 IoC 超出了这个问题的范围。
    • @toxic,对不起,我在之前的评论中说错了。主应用程序引用了 BLL,DAL 也引用了 BLL(因为 BLL 包含 MyMemberRepo 类需要实现的 IGenericRepository)。其余的都是正确的。
    • 很好,我大致了解了发生了什么。我有另一个想法......在业务层和数据访问层中定义实体 在覆盖方法中对业务实体使用 Fluent API 并仅使用它并删除数据访问层中的实体,这样我不会复制实体,但同时我是使用相同的实体...您对此有何看法
    • @toxic,这就是你需要做出判断的地方。纯粹主义者会说您应该将 MemberDto 类保留在 DAL 中,因为它们装饰有 [Table][Key] 等属性,这些属性是特定于数据访问的。在许多情况下,这是一个合理的建议,因为它严格分离了各层之间的关注点,并且可以使您的应用程序更加灵活和长期可维护。然而,这种灵活性是以“重复工作”(即本质上重复的实体和映射任务)为代价的。
    猜你喜欢
    • 2014-01-23
    • 2018-08-03
    • 2017-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多