Linq к SQL: порядок выполнения при вызове SubmitChanges ()

IntelliJ имеет довольно продвинутые проверки кода (сравнимые, но отличающиеся от FindBugs).

Хотя я серьезно скучаю по плагину FindBugs при использовании IntelliJ (интеграция Eclipse / FindBugs довольно крутая).

Здесь - это официальный список CodeInspections, поддерживаемых IntelliJ

РЕДАКТИРОВАТЬ: Наконец, есть findbugs-плагин для IntelliJ. Это все еще немного бета, но комбинация Code Inspections и FindBugs просто великолепна!

20
задан Fabian Steeg 30 January 2009 в 16:03
поделиться

4 ответа

Да, по какой-то причине Linq to SQL выполняет все удаления в последнюю очередь. И нет никакого способа изменить это.

Или, может быть, есть. Я не заглядывал в DataContext кодогенератора, чтобы посмотреть, можем ли мы что-то там переопределить.

Вы можете вызывать SubmitChanges () сколько угодно раз. Мой обходной путь, когда мне нужно удалить в первую очередь, - это отметить мои удаления, вызвать SubmitChanges (), затем выполнить вставки и обновления и снова вызвать SubmitChanges.

Вы можете обернуть все внутри TransactionScope:

    var deletables =
        from toDelete in db.NamedValues
        where toDelete.Name == knownValue.Name
        select toDelete;

    using (var scope = new TransactionScope())
    {
        db.NamedValues.DeleteAllOnSubmit(deletables);
        db.SubmitChanges();

        db.NamedValues.InsertOnSubmit(knownValue);
        db.SubmitChanges();

        scope.Complete();
    }
19
ответ дан 30 November 2019 в 00:48
поделиться

I have been having this same problem. I came up with a hack to work around it, which seems to work for me: I manually execute some SQL for each potentially problematic delete in the change set before calling SubmitChanges():

foreach (object o in m_Db.GetChangeSet().Deletes)
{
    LibraryMember m = o as LibraryMember;

    if (m != null)
    {
        m_Db.ExecuteCommand("DELETE FROM LibraryMembers WHERE LibraryMemberId={0}", m.LibraryMemberId);
    }
}

m_Db.SubmitChanges()
3
ответ дан 30 November 2019 в 00:48
поделиться

Другое решение - прикрепить изменения к другому контексту данных в правильном порядке. Однако недостатком этого решения является то, что любые объекты, на которые все еще ссылается остальная часть вашего приложения, которые были из исходного контекста данных, теперь будут недействительными: (

Я пробовал небольшой вариант этого, создав второй временный контекст данных для фиксации. Но я не могу понять, как тогда привести исходный контекст данных в чистое состояние.

Это очень расстраивает: (

public void Save()
{
    string connectionString = m_Db.Connection.ConnectionString;
    IList<object> deletes = m_Db.GetChangeSet().Deletes;
    IList<object> inserts = m_Db.GetChangeSet().Inserts;
    IList<object> updates = m_Db.GetChangeSet().Updates;

    m_Db.Dispose();
    m_Db = new MyDataContext(connectionString);

    Attach(m_Db, deletes);
    m_Db.SubmitChanges();
    Attach(m_Db, updates);
    m_Db.SubmitChanges();
    Attach(m_Db, inserts);
    m_Db.SubmitChanges();
}

void Attach(DataContext context, IList<object> items)
{
    foreach (object o in items)
    {
        context.GetTable(o.GetType()).Attach(Clone(o));
    }
}

object Clone(object o)
{
    object result = o.GetType().GetConstructor(Type.EmptyTypes).Invoke(null);
    foreach (PropertyInfo property in o.GetType().GetProperties())
    {
        if (property.PropertyType.IsValueType)
        {
            property.SetValue(result, property.GetValue(o, null), null);
        }
    }
    return result;
}
1
ответ дан 30 November 2019 в 00:48
поделиться

Вместо того, чтобы просто выбрасывать всех детей и воссоздавать их, подумайте о том, чтобы приложить немного больше усилий и сделать это в два этапа: добавьте элементы, которые еще не добавлены, и удалите те, которые добавлено ранее, но больше не желательно. Например, на сайте ThinqLinq.com у меня есть сообщения, которые можно назначать категориям. На экране редактирования я предоставляю список категорий, которые можно выбрать и отменить. Когда я получаю сообщение, содержащее список выбранных категорий, я использую следующее для удаления и обновления соответствующих записей:

Dim selectedCats() As String = CType(ValueProvider("categories").RawValue, String())
For Each catId In selectedCats.Except(From cp In currentPost.CategoryPosts _
                                      Select id = cp.CategoryID.ToString())
   'Add new categories
   currentPost.CategoryPosts.Add(New CategoryPost With {.CategoryID = CInt(catId)})
Next

'Delete removed categories
dc.CategoryPosts.DeleteAllOnSubmit(From cp In currentPost.CategoryPosts _
                                   Where Not selectedCats.Contains(cp.CategoryID.ToString))
0
ответ дан 30 November 2019 в 00:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: