将 Linq 克隆到 Sql 实体 - 分离数据上下文
Posted
技术标签:
【中文标题】将 Linq 克隆到 Sql 实体 - 分离数据上下文【英文标题】:Cloning a Linq to Sql Entity - detaching data context 【发布时间】:2012-01-12 20:56:56 【问题描述】:我需要克隆一个 Linq to SQL 实体。概览:
Customer origCustomer = db.Customers.SingleOrDefault(c => c.CustomerId == 5);
Customer newCustomer = CloneUtils.Clone(origCustomer);
newCustomer.CustomerId = 0; // Clear key
db.Customers.InsertOnSubmit(newCustomer);
db.SubmitChanges(); // throws an error
其中 CloneUtils.Clone() 是一个简单的通用方法,它使用反射将数据从原始实体复制到新实体。
我遇到的问题是,当我尝试将新实体添加回数据库时,出现以下错误:
已尝试附加或添加一个不是新的实体,可能是从另一个 DataContext 加载的。这不受支持。
我似乎找不到从数据上下文中分离克隆实体的简单/通用方法。或者我可以调整我的克隆方法以“跳过”上下文相关字段?
谁能指出我正确的方向?
谢谢。
为了完整起见,这是我按照 Marcus 的建议最终得出的方法:
public static T ShallowClone<T>(T srcObject) where T : class, new()
// Get the object type
Type objectType = typeof(T);
// Get the public properties of the object
PropertyInfo[] propInfo = srcObject.GetType()
.GetProperties(
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.Public
);
// Create a new object
T newObject = new T();
// Loop through all the properties and copy the information
// from the source object to the new instance
foreach (PropertyInfo p in propInfo)
Type t = p.PropertyType;
if ((t.IsValueType || t == typeof(string)) && (p.CanRead) && (p.CanWrite))
p.SetValue(newObject, p.GetValue(srcObject, null), null);
// Return the cloned object.
return newObject;
【问题讨论】:
【参考方案1】:只克隆公共属性
var PropertyBindings = BindingFlags.Public | BindingFlags.Instance;
即值类型或字符串
var PropType = p.PropertyType.IsValueType || p.PropertyType == typeof(string);
而且是可以访问的
var IsAccessible = p.CanRead && p.CanWrite;
【讨论】:
以上是关于将 Linq 克隆到 Sql 实体 - 分离数据上下文的主要内容,如果未能解决你的问题,请参考以下文章
在运行时将实体对象添加到 LINQ-to-SQL 数据上下文 - SQL、C#(WPF)