Клонирование сущности Linq to Sql - отсоединение контекста данных - PullRequest
7 голосов
/ 13 января 2012

У меня есть требование клонировать сущность 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 () - это простой универсальный метод, который использует отражение для копирования копии данных из исходного объекта в новый объект.

Проблема Iесть то, что когда я пытаюсь добавить новую сущность обратно в базу данных, я получаю следующую ошибку:

Была предпринята попытка присоединить или добавить не новую сущность, возможно, загруженную из другой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;
}

1 Ответ

6 голосов
/ 13 января 2012

Только клонировать открытые свойства

var PropertyBindings = BindingFlags.Public | BindingFlags.Instance;

Это типы значений или строки

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

И доступные

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