关于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); }
在某些情况下会导致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); } } }
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); } } }