克隆 Linq to Sql 实体 - 分离数据上下文

发布于 2024-12-27 05:31:26 字数 1477 浏览 3 评论 0原文

我需要克隆 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 加载的。不支持此操作。

我似乎找不到一种简单/通用的方法将克隆实体与数据上下文分离。或者也许我可以调整我的克隆方法以“跳过”上下文相关字段?

有人能指出我正确的方向吗?

谢谢。

为了完整起见,这是我最终遵循马库斯建议的方法:

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;
}

I have a requirement to clone a Linq to SQL entity. In overview:

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

where CloneUtils.Clone() is a simple generic method that uses reflection to copy the copy the data from the original entity to the new entity.

The problem I have is that when I try and add the new entity back into the database, I get the following error:

An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported.

I can't seem to find an easy/generic way of detaching the cloned entity from the data context. Or maybe I can adjust my cloning method to 'skip' the context related fields?

Can anyone point me in the right direction?

Thanks.

For completeness, here is the method I ended up with following Marcus's advice:

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

給妳壹絲溫柔 2025-01-03 05:31:26

公共属性

var PropertyBindings = BindingFlags.Public | BindingFlags.Instance;

仅克隆值类型或字符串

var PropType = p.PropertyType.IsValueType || p.PropertyType == typeof(string);

且可访问的

 var IsAccessible = p.CanRead && p.CanWrite;

Only clone public properties

var PropertyBindings = BindingFlags.Public | BindingFlags.Instance;

That are value types or string

var PropType = p.PropertyType.IsValueType || p.PropertyType == typeof(string);

And that are accessible

 var IsAccessible = p.CanRead && p.CanWrite;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文