首页新闻找找看学习计划

关于Entity和DTO之间属性关系转换的方案?

0
悬赏园豆:10 [已解决问题] 解决于 2013-09-18 20:32

如以下贴出的代码:

我的需求就是,Entity是针对数据库存储的,DTO是针对业务数据传输的。

我就是想把Entity和DTO之间的转换封装起来,但是如果DTO之间存在关联的时候,转换的时候就会有递归调用的问题,我不想每次在业务层读取Entity之后再把对应的属性依次复制到DTO上面,把Entity和DTO的转换进行内部封装,就不用每次都做重复的事情。看来我现在的方案行不通,希望各位园友提供更好的思路。

对于我现在的处理方式,可能会在FromEntity里面复制一般属性,比如像List<OrgNode>这种关系的,留在业务层那里,根据业务场景,做出相应的复制或者加载。

各位请多多指教^_^

 

示例代码:

///////////////////////////////////////// Entity 代码 //////////////////////////////

public
class OrgChart { public int Id { get; set; } public string Name { get; set; } public OrgNode Root { get; set; } public IList<OrgNode> Nodes { get; set; } } public class OrgNode { public int Id { get; set; } public string Name { get; set; } public string Type { get; set; } public OrgChart Chart { get; set; } public OrgNode Parent { get; set; } public IList<OrgNode> ChildNodes { get; set; } }


///////////////////////////////////////// DTO代码 //////////////////////////////
public interface IBaseDTO<T> { T ToEntity(); void FromEntity(T entity); } public class OrgChartDTO : IBaseDTO<OrgChart>{ public int Id { get; set; } public string Name { get; set; } public OrgNodeDTO Root { get; set; } public IList<OrgNodeDTO> Nodes { get; set; } public OrgChart ToEntity() { //省略 } public void FromEntity(OrgChart entity) { //其他属性 if(entity.Root != null) { this.Root = new OrgNodeDTO(); //#关键代码! //1.当Root(OrgNode)调用FromEntity方法则进入OrngNode的FromEntity(看一下OrgNode代码) this.Root.FromEntity(entity); } } } public class OrgNodeDTO : IBaseDTO<OrgNode>{ public int Id { get; set; } public string Name { get; set; } public string Type { get; set; } public OrgChartDTO Chart { get; set; } public OrgNodeDTO Parent { get; set; } public IList<OrgNodeDTO> ChildNodes { get; set; } public OrgNode ToEntity() { //省略 } public void FromEntity(OrgNode entity) { //其他属性 if(entity.Chart != null) { OrgChartDTO chartDTO = new OrgChartDTO(); //#关键代码! //2.因为OrgNode关联OrgChart,所以从OrgChart的Root.FromEntity()之后,就不停的递归。 // OrChart.FormEntity->Root.FromEntity->Root.OrgChart.FromEntity->OrgChart.Root.FromEntity->..., // 直到StackOverflowException. chartDTO.FromEntity(entity.Chart); this.Chart = chartDTO; } } }
kaleyroy的主页 kaleyroy | 初学一级 | 园豆:160
提问于:2013-09-18 12:02
< >
分享
最佳答案
0

用 AutoMapper。

收获园豆:8
Launcher | 高人七级 |园豆:45040 | 2013-09-18 12:33

这个真心强大,非常感谢!

kaleyroy | 园豆:160 (初学一级) | 2013-09-18 20:29

automapper 好像不能忽略源对象中null属性
https://github.com/AutoMapper/AutoMapper/issues/1406

yourebi | 园豆:184 (初学一级) | 2019-03-19 21:33
其他回答(1)
0

/// <summary>
        /// Dto对象转Entity,只是复制属性,dto的属性要比entity少2个哦。
        /// </summary>
        /// <typeparam name="T">EntityObject</typeparam>
        /// <param name="dto">dto对象</param>
        /// <returns>EntityObject对应的实例</returns>
        public EntityObject ConvertToEntityObject<T>(object dto) where T : EntityObject
        {
            Type dtoEntity = dto.GetType();
            var piList = dtoEntity.GetProperties().Where(p => p.PropertyType.IsPublic == true).ToList();
            Assembly assembly = Assembly.GetAssembly(typeof(T));
            object resultObj = assembly.CreateInstance(string.Join(".",new string[]{typeof(T).Namespace,typeof(T).Name}));
            var piResultObj = resultObj.GetType().GetProperties().Where(p => p.PropertyType.IsPublic == true).ToList();
            foreach (System.Reflection.PropertyInfo pi in piList)
            {
                var sourcePi = piResultObj.Single(p => p.Name == pi.Name);
                 if (sourcePi != null)
                 {
                     object value = pi.GetValue(dto, null);
                     sourcePi.SetValue(resultObj, value, null);
                 }                   
            }
            return resultObj as EntityObject;
        }

收获园豆:2
数据酷软件 | 园豆:26 (初学一级) | 2013-09-18 18:03

目前有更好的方案,自己写反射暂时不考虑,谢谢^_^

支持(0) 反对(0) kaleyroy | 园豆:160 (初学一级) | 2013-09-18 20:30
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册