遗忘海岸

江湖程序员 -Feiph(LM战士)

导航

关于EF与EmitMapper

对应以下代码

        public static void CloneEFModel<TFrom, TTo>(TFrom from, TTo to)
            where TFrom : class
            where TTo : class
        {
            var map = ObjectMapperManager.DefaultInstance.GetMapper<TFrom, TTo>(new DefaultMapConfig().IgnoreMembers<TFrom, TTo>(new string[] { "EntityKey","EntitySet" })); //EntityKey
            map.Map(from, to);

        }

        public static void CloneEFModel2<TFrom, TTo>(TFrom from, TTo to)
            where TFrom : class
            where TTo : class
        {

            var config = new DefaultMapConfig().IgnoreMembers<TFrom, TTo>(new string[] { "EntityKey", "EntityState" });
            config.SetConfigName("NoEntityKey");
            var map = EmitMapper.ObjectMapperManager.DefaultInstance.GetMapper<TFrom, TTo>(config);
            var config2 = map.MapperImpl.MappingConfigurator as DefaultMapConfig;
             map.Map(from, to);

        }
View Code

在某些情况下会导致map后to 实体的EntityKey被设置成from ,这样在添加到数据库时报EntitySet不匹配的错误,

企图查找源代码,但是-----------------

于是针对EF映射添加了下面代码

 

        public static void CloneEFModel2<TFrom, TTo>(TFrom from, TTo to)
            where TFrom : EntityObject
            where TTo : EntityObject
        {
            var flag=false;
            if (to.EntityKey == null) flag = true;
            var map = ObjectMapperManager.DefaultInstance.GetMapper<TFrom, TTo>(new DefaultMapConfig().IgnoreMembers<TFrom, TTo>(new string[] { "EntityKey" })); //EntityKey
            map.Map(from, to);

            if (to.EntityKey != null && flag)
            {
                to.EntityKey = null;
            }
        }

 进一步测试发现是在做ZJ_KB  map  ZJ_Task_Card 时,由于ZJ_KB.YTParamList  map  ZJ_Task_Card.YTParamList 时会先生成一个映射,而这个映射是EmitMapper内部生成的他没有采用

指定的忽略EnitityKey属性, 而这个一旦生成后 YT_KB_Param map  YT_Task_Card_Param 时就会使用这个配置。所以就发生了错误

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using EmitMapper;
using EmitMapper.MappingConfiguration;
using com.geelyhd.MFG.EFModel;
using System.Data.Objects.DataClasses;

namespace WinUI
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
        }

        private void Test()
        {
            var card = new ZJ_Task_Card();
            var kb = new ZJ_KB();
           
            //using (var ctx = DBCtx.GetCraftHisCtx())
            //{
            //   kb= ctx.ZJ_KB.FirstOrDefault();
            //   ctx.Detach(kb);
            //}
            var taskItem = new ZJ_TaskItems();
            //using (var ctx = DBCtx.GetCraftHisCtx())
            //{
            //    taskItem = ctx.ZJ_TaskItems.FirstOrDefault();
            //    ctx.Detach(taskItem);
            //}
            CloneEFModel<ZJ_KB, ZJ_Task_Card>(kb, card);

            //CloneEFModel<ZJ_TaskItems, ZJ_Task_Card>(taskItem, card);
            //var bomFrom = new ZJ_KB_BOM();
            //var bomTo = new ZJ_Task_Card_BOM();
            //CloneEFModel<ZJ_KB_BOM, ZJ_Task_Card_BOM>(bomFrom, bomTo);
            //var zJKBParam = new ZJ_KB_Param();
            //var zJTaskCardParam = new ZJ_Task_Card_Param();
            //CloneEFModel<ZJ_KB_Param, ZJ_Task_Card_Param>(zJKBParam, zJTaskCardParam);
            CloneEFModel<ZJ_KB, ZJ_Task_Card>(kb, card);
            var yTTaskCardParamList = new List<YT_Task_Card_Param>();
            var yTParamList = LoadList();
            foreach (var p in yTParamList)
            {
                var paramYTEnt = new YT_Task_Card_Param();
                CloneEFModel<YT_KB_Param, YT_Task_Card_Param>(p, paramYTEnt, "YTParamList");
                paramYTEnt.AddEmpNo = "06002";
                paramYTEnt.AddTime = DateTime.Now;
                paramYTEnt.CardId = 1233;
                paramYTEnt.TaskId = 3333;
                //paramEnt.EntityKey = null;
                yTTaskCardParamList.Add(paramYTEnt);

            }
        }

        private static List<YT_KB_Param> LoadList()
        {
            var yTParamList = new List<YT_KB_Param>();
            using (var ctx = DBCtx.GetCraftHisCtx())
            {
                yTParamList = ctx.YT_KB_Param.ToList();
                foreach (var it in yTParamList)
                {
                    ctx.Detach(it);
                }
                var first = yTParamList.FirstOrDefault();
                yTParamList.Clear();
                yTParamList.Add(first);
            }
            return yTParamList;
        }

        public static void CloneEFModel<TFrom, TTo>(TFrom from, TTo to,params string[] ignoreArr)
            where TFrom : class
            where TTo : class
        {
            var ignoreList=  new List<String>() { "EntityKey" };
            if (ignoreArr!=null && ignoreArr.Length>0)
            {
                ignoreList.AddRange(ignoreArr);
            }
            
            var config = new DefaultMapConfig().IgnoreMembers<TFrom, TTo>(ignoreList.ToArray());
            var map = ObjectMapperManager.DefaultInstance.GetMapper<TFrom, TTo>(config); //EntityKey
            map.Map(from, to);
            Console.WriteLine(map.MapperImpl.MappingConfigurator.GetHashCode());
            if ((to as EntityObject).EntityKey != null)
            {
                Console.WriteLine("异常出现" + (to as EntityObject).EntityKey.EntitySetName);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Test();
            Console.WriteLine("测试完毕:" + DateTime.Now);
        }
    }
}
View Code

 

CloneEFModel<YT_KB_Param, YT_Task_Card_Param>(new YT_KB_Param(), new YT_Task_Card_Param()); //先执行 生成配置
CloneEFModel<ZJ_KB, ZJ_Task_Card>(kb, card); //会使用上一句生成的配置

CloneEFModel<YT_KB_Param, YT_Task_Card_Param>(p, paramYTEnt);  //这里就是符合预期的

 //以下测试了命名方式,如果同一配置命名下执行照样有问题

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using EmitMapper;
using EmitMapper.MappingConfiguration;
using com.geelyhd.MFG.EFModel;
using System.Data.Objects.DataClasses;

namespace WinUI
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
        }

        private void Test()
        {
            var card = new ZJ_Task_Card();
            var kb = new ZJ_KB();
           
            //using (var ctx = DBCtx.GetCraftHisCtx())
            //{
            //   kb= ctx.ZJ_KB.FirstOrDefault();
            //   ctx.Detach(kb);
            //}
            var taskItem = new ZJ_TaskItems();
            //using (var ctx = DBCtx.GetCraftHisCtx())
            //{
            //    taskItem = ctx.ZJ_TaskItems.FirstOrDefault();
            //    ctx.Detach(taskItem);
            //}
           // CloneEFModel<YT_KB_Param, YT_Task_Card_Param>(new YT_KB_Param(), new YT_Task_Card_Param());
            //CloneEFModel3<ZJ_KB, ZJ_Task_Card>(kb, card);

            //CloneEFModel<ZJ_TaskItems, ZJ_Task_Card>(taskItem, card);
            //var bomFrom = new ZJ_KB_BOM();
            //var bomTo = new ZJ_Task_Card_BOM();
            //CloneEFModel<ZJ_KB_BOM, ZJ_Task_Card_BOM>(bomFrom, bomTo);
            //var zJKBParam = new ZJ_KB_Param();
            //var zJTaskCardParam = new ZJ_Task_Card_Param();
            //CloneEFModel<ZJ_KB_Param, ZJ_Task_Card_Param>(zJKBParam, zJTaskCardParam);
            CloneEFModel3<ZJ_KB, ZJ_Task_Card>(kb, card,"Param_KBToTask");

            var yTTaskCardParamList = new List<YT_Task_Card_Param>();
            var yTParamList = LoadList();
            foreach (var p in yTParamList)
            {
                var paramYTEnt = new YT_Task_Card_Param();
                CloneEFModel3<YT_KB_Param, YT_Task_Card_Param>(p, paramYTEnt,"Param_KBToTask");
                paramYTEnt.AddEmpNo = "06002";
                paramYTEnt.AddTime = DateTime.Now;
                paramYTEnt.CardId = 1233;
                paramYTEnt.TaskId = 3333;
                //paramEnt.EntityKey = null;
                yTTaskCardParamList.Add(paramYTEnt);

            }
        }

        private static List<YT_KB_Param> LoadList()
        {
            var yTParamList = new List<YT_KB_Param>();
            using (var ctx = DBCtx.GetCraftHisCtx())
            {
                yTParamList = ctx.YT_KB_Param.ToList();
                foreach (var it in yTParamList)
                {
                    ctx.Detach(it);
                }
                var first = yTParamList.FirstOrDefault();
                yTParamList.Clear();
                yTParamList.Add(first);
            }
            return yTParamList;
        }
        public static void CloneEFModel3<TFrom, TTo>(TFrom from, TTo to, string configName = "NoEntityKey")
            where TFrom : class
            where TTo : class
        {

            var config = new DefaultMapConfig().IgnoreMembers<TFrom, TTo>(new string[] { "EntityKey", "EntityState" });
            config.SetConfigName(configName);
            var map = EmitMapper.ObjectMapperManager.DefaultInstance.GetMapper<TFrom, TTo>(config);
            var config2 = map.MapperImpl.MappingConfigurator as DefaultMapConfig;
            map.Map(from, to); 
            if ((to as EntityObject).EntityKey != null)
            {
                Console.WriteLine("异常出现" + (to as EntityObject).EntityKey.EntitySetName);
            }

        }
        public static void CloneEFModel<TFrom, TTo>(TFrom from, TTo to,params string[] ignoreArr)
            where TFrom : class
            where TTo : class
        {
            var ignoreList=  new List<String>() { "EntityKey" };
            if (ignoreArr!=null && ignoreArr.Length>0)
            {
                ignoreList.AddRange(ignoreArr);
            }
            
            var config = new DefaultMapConfig().IgnoreMembers<TFrom, TTo>(ignoreList.ToArray());
            var map = ObjectMapperManager.DefaultInstance.GetMapper<TFrom, TTo>(config); //EntityKey
            map.Map(from, to);
            Console.WriteLine(map.MapperImpl.MappingConfigurator.GetHashCode());
            if ((to as EntityObject).EntityKey != null)
            {
                Console.WriteLine("异常出现" + (to as EntityObject).EntityKey.EntitySetName);
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Test();
            Console.WriteLine("测试完毕:" + DateTime.Now);
        }
    }
}
View Code

 

但是由于无法保证系统到底先执行那个,所以还是手动设置 Ent.EntityKey=null 是最靠谱的。

posted on 2020-12-28 09:23  遗忘海岸  阅读(148)  评论(0编辑  收藏  举报