Repository pattern and mapping between domain models and Entity Framework

后端 未结 6 1169
后悔当初
后悔当初 2020-12-04 07:15

My repositories deal with and provide persistence for a rich domain model. I do not want to expose the anemic, Entity Framework data entity to my business layers, so I need

6条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-04 07:44

    Let's say you have the following data access object...

    public class AssetDA
    {        
        public HistoryLogEntry GetHistoryRecord(int id)
        {
            HistoryLogEntry record = new HistoryLogEntry();
    
            using (IUnitOfWork uow = new NHUnitOfWork())
            {
                IReadOnlyRepository repository = new NHRepository(uow);
                record = repository.Get(id);
            }
    
            return record;
        }
    }
    

    which returns a history log entry data entity. This data entity is defined as follows...

    public class HistoryLogEntry : IEntity
    {
        public virtual int Id
        { get; set; }
    
        public virtual int AssetID 
        { get; set; }
    
        public virtual DateTime Date
        { get; set; }
    
        public virtual string Text
        { get; set; }
    
        public virtual Guid UserID
        { get; set; }
    
        public virtual IList Details { get; set; }
    }
    

    You can see that the property Details references another data entity AssetHistoryDetail. Now, in my project I need to map these data entities to Domain model objects which are used in my business logic. To do the mapping I have defined extension methods...I know it's an anti-pattern since it is language specific, but the good thing is that it isolate and breaks dependencies between each other...yeah, that's the beauty of it. So, the mapper is defined as follows...

    internal static class AssetPOMapper
    {
        internal static HistoryEntryPO FromDataObject(this HistoryLogEntry t)
        {
            return t == null ? null :
                new HistoryEntryPO()
                {
                    Id = t.Id,
                    AssetID = t.AssetID,
                    Date = t.Date,
                    Text = t.Text,
                    UserID = t.UserID,
                    Details = t.Details.Select(x=>x.FromDataObject()).ToList()
                };
        }
    
        internal static AssetHistoryDetailPO FromDataObject(this AssetHistoryDetail t)
        {
            return t == null ? null :
                new AssetHistoryDetailPO()
                {
                    Id = t.Id,
                    ChangedDetail = t.ChangedDetail,
                    OldValue = t.OldValue,
                    NewValue = t.NewValue
                };
        }
    }
    

    and that's pretty much it. All dependencies are in one place. Then, when calling a data object from the business logic layer I'd let LINQ do the rest...

    var da = new AssetDA();
    var entry =  da.GetHistoryRecord(1234);
    var domainModelEntry = entry.FromDataObject();
    

    Note that you can define the same to map Domain Model objects to Data Entities.

提交回复
热议问题