LINQ to SQL: создание детализированного объекта - PullRequest
1 голос
/ 10 февраля 2010

Я сгенерировал несколько классов, использующих LINQ to SQL

один из них "Клиент"

Теперь я хочу создать отключенный объект Customer.

т.е. Я могу создать объект, сохранить его в сеансе, а затем присоединить его обратно, только если захочу. Не автоматически Следовательно, только если я присоединяю его - это должно повлиять на мой контекст SubmitChange (), иначе нет.

Возможно ли это?

Также можно ли добавить этот отсоединенный объект в коллекцию прикрепленных объектов, не затрагивая SubmitChanges (), или при добавлении отсоединенный объект снова присоединится?

Ответы [ 3 ]

1 голос
/ 10 февраля 2010

Нет метода «Отсоединить», но это возможно при сериализации:

Customer customerCopy;
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
    bf.Serialize(ms, customer);
    ms.Position = 0;
    customerCopy = (Customer)bf.Deserialize(ms);
}

Имейте в виду, что это неудобно повторно прикреплять объект позже. Табличный метод Attach является привередливым - для его работы обычно требуется столбец Version (тип отметки времени) для сущности.

Примечание. Я просто перечитал ваш вопрос, и звучит так, будто вы просто хотите построить объект. Если это так, то создание нового Customer через new Customer() будет , а не , создать присоединенную сущность. Он присоединяется только после вызова метода InsertOnSubmit или Attach для таблицы.

Кроме того, вы можете свободно добавлять отсоединенные сущности к List<Customer> (или подобному), содержащему присоединенные сущности - Linq to SQL не заботится об этом, сущность присоединяется только в том случае, если она выдана самой DataContext вы прикрепляете его одним из способов, указанных выше.

0 голосов
/ 13 июля 2012

Виталий, Извините, я потерял этот пост. У меня все еще есть код.

public class EntityBase : IEntityBase
{
    /// <summary>
    /// Detaches the entity, so it can be added to another dataContext. It does this by setting
    /// all the FK properties to null/default.
    /// </summary>
    public void Detach()
    {
        // I modified the .tt file to generate the Initialize method by default. 
        // The call to OnCreated() is moved to the constructor.
        GetType().GetMethod("Initialize", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(this, null);
    }
}

А вот и вызов функции Detach () из моего адаптера

public class OrderAdapter : IOrderAdapter
{
    public void Add(IOrder order)
    {
        try
        {
            using (var db = new ATPDataContext())
            {
                Order newOrder = (Order)order;
                newOrder.Detach(); // not required for insertion, but to keep references to Product 
                db.Orders.InsertOnSubmit(newOrder);
                db.SubmitChanges();
            }
        }
        catch (Exception ex)
        {                
        }
    }
 }

А в моем .tt файле

#region Construction
public <#=class1.Name#>()
{
    Initialize();

    <# if (class1.HasPrimaryKey) {#>
        OnCreated();
    <# } #>
}

private void Initialize()
{
<#        foreach(Association association in class1.Associations) { #>
        <#=association.Storage#> = <#
        if (association.IsMany) {
            #>new EntitySet<<#=association.Type.Name#>>(attach_<#=association.Member#>, detach_<#=association.Member#>);
<#          } else {
            #>default(EntityRef<<#=association.Type.Name#>>); 
<#          }
    }
#>
    }
#endregion

НТН!

0 голосов
/ 30 июля 2010

Для Linq to Sql поддерживается только DataContractSerializer.

Существует более эффективный способ отсоединения (), использующий следующий базовый метод:

public void Detach()
{
   GetType().GetMethod("Initialize", BindingFlags.Instance |         
      BindingFlags.NonPublic).Invoke(this, null);
}

Это вызовет метод Initialize (), который «сбросит» все свойства FK. Хитрость в том, что этот метод генерируется только тогда, когда включена сериализация. Есть способ обойти это, проверьте здесь для получения дополнительной информации

...