Как обработать вложенный datacontext в BL?

Выезд DBVisualiser и SQL-клиент SQuirreL . Оба из них имеют поддержку HSQLDB и GUI для редактирования/изменения/просмотра таблицы.

7
задан Eran Betzalel 29 August 2009 в 16:08
поделиться

4 ответа

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

Вы не одиноки в путанице по поводу передовых методов работы с контекстами данных. Если вы поищете это в Интернете, ответы найдутся по всей карте. В вашем примере вы можете передать контекст данных в метод AddFile. Или вы можете реорганизовать этот доступ к данным в класс, который поддерживает время жизни контекста данных до тех пор, пока папка и файлы не будут сохранены. Рик Стрел опубликовал статью о нескольких методах.

Тем не менее, ни один из ответов, которые я видел по LINQ to SQL, не кажется мне очень удовлетворительным. Рассматривали ли вы возможность избежать управления уровнем данных с помощью ORM? Я успешно использовал NetTiers , но слышал хорошие отзывы о PLINQO . Оба они требуют CodeSmith , но есть много альтернатив .

ответы есть по всей карте. В вашем примере вы можете передать контекст данных в метод AddFile. Или вы можете реорганизовать этот доступ к данным в класс, который поддерживает время жизни контекста данных до тех пор, пока папка и файлы не будут сохранены. Рик Стрел опубликовал статью о нескольких методах.

Тем не менее, ни один из ответов, которые я видел по LINQ to SQL, не кажется мне очень удовлетворительным. Рассматривали ли вы возможность избежать управления уровнем данных с помощью ORM? Я успешно использовал NetTiers , но слышал хорошие отзывы о PLINQO . Оба они требуют CodeSmith , но есть много альтернатив .

ответы есть по всей карте. В вашем примере вы можете передать контекст данных в метод AddFile. Или вы можете реорганизовать этот доступ к данным в класс, который поддерживает время жизни контекста данных до тех пор, пока папка и файлы не будут сохранены. Рик Стрел опубликовал статью о нескольких методах.

Тем не менее, ни один из ответов, которые я видел по LINQ to SQL, не кажется мне очень удовлетворительным. Рассматривали ли вы возможность избежать управления уровнем данных с помощью ORM? Я успешно использовал NetTiers , но слышал хорошие отзывы о PLINQO . Оба они требуют CodeSmith , но есть много альтернатив .

вы можете реорганизовать этот доступ к данным в класс, который поддерживает время жизни контекста данных до тех пор, пока все файлы и папка не будут сохранены. Рик Стрел опубликовал статью о нескольких методах.

Тем не менее, ни один из ответов, которые я видел по LINQ to SQL, не кажется мне очень удовлетворительным. Рассматривали ли вы возможность избежать управления уровнем данных с помощью ORM? Я успешно использовал NetTiers , но слышал хорошие отзывы о PLINQO . Оба они требуют CodeSmith , но есть много альтернатив .

вы можете реорганизовать этот доступ к данным в класс, который поддерживает время жизни контекста данных до тех пор, пока все файлы и папка не будут сохранены. Рик Стрел опубликовал статью о нескольких методах.

Тем не менее, ни один из ответов, которые я видел по LINQ to SQL, не кажется мне очень удовлетворительным. Рассматривали ли вы возможность избежать управления уровнем данных с помощью ORM? Я успешно использовал NetTiers , но слышал хорошие отзывы о PLINQO . Оба они требуют CodeSmith , но есть много альтернатив .

Рассматривали ли вы возможность избежать управления уровнем данных с помощью ORM? Я успешно использовал NetTiers , но слышал хорошие отзывы о PLINQO . Оба они требуют CodeSmith , но есть много альтернатив .

Рассматривали ли вы возможность избежать управления уровнем данных с помощью ORM? Я успешно использовал NetTiers , но слышал хорошие отзывы о PLINQO . Оба они требуют CodeSmith , но есть много альтернатив .

3
ответ дан 7 December 2019 в 14:36
поделиться

Я придумал способ справляться с такими ситуациями.

Пример базового класса для объекта BL (объект наследует этот класс)

abstract public class TestControllerBase : IDisposable
{
    public TestDataContext CurrentDataContext { get; private set; }

    protected TestControllerBase()
    {
        CurrentDataContext = new TestDataContext();
    }

    protected TestControllerBase(TestDataContext dataContext)
    {
        CurrentDataContext = dataContext;
    }

    protected void ClearDataContext()
    {
        CurrentDataContext.Dispose();
        CurrentDataContext = new TestDataContext();
    }

    public void Dispose()
    {
        CurrentDataContext.Dispose();
    }
}

Реализованный контроллер

public sealed class BLTestController : TestControllerBase
{
    public BLTestController() { }

    public BLTestController(TestDataContext dataContext)
        : base(dataContext) { }

    //  The entity functions will be implemented here using CurrentDataContext
}

Простое использование реализованного контроллера

var testController = new BLTestControllerA();

testController.DeleteById(1);

Более сложное использование реализованного контроллера (2 контроллера в одном DataContext)

var testControllerA = new BLTestControllerA();
var testControllerB = new BLTestControllerB(testControllerA.CurrentDataContext);

testControllerA.DeleteById(1);
testControllerB.DeleteById(1);

Я хотел бы увидеть больше идей по решению этой загадки и комментарии по поводу приведенного выше кода.

0
ответ дан 7 December 2019 в 14:36
поделиться

Для этой транзакции не нужно выполнять 2 или более обходов. Я считаю, что LINQ-DataContext умен, чтобы распознать, что эти файлы принадлежат объекту папки, и сначала вставит строку папки, а затем файлы (все в контексте транзакции, например BEGIN TRAN / COMMIT). Однако вам нужно сделать:

dc.Files.InsertOnSubmit(
                new File { Filename = filename, Folder = folder });

вместо FolderId. Примерно так:

public class TestBL
{
    public static void AddFolder(string folderName)
    {
        using (var ts = new TransactionScope())
        {
            using (var dc = new TestDataContext())
            {
                var folder = new Folder { FolderName = folderName };

                AddFile(dc, "test1.xyz", folder);
                AddFile(dc, "test2.xyz", folder);
                AddFile(dc, "test3.xyz", folder);

                dc.SubmitChanges();
            }

            ts.Complete();
        }
    }

    private static void AddFile(DataContext dc, string filename, Folder folder)
    {
            dc.Files.InsertOnSubmit(
                new File { Filename = filename, Folder = folder });
    }

    public static void AddFile(string filename, int folderId)
    {
        using (var dc = new TestDataContext())
        {
            var folder = new Folder { FolderId = folderId };
            dc.Attach(folder, false);
            AddFile(dc, filename, folder);

            dc.SubmitChanges();
        }
    }
}

На ваш вопрос относительно DTC: Я не думаю, что здесь возможно избежать DTC из-за 2 открытых соединений. Я считаю, что они недавно внесли некоторые изменения в этой области, см. здесь , но описанный там сценарий немного отличается (2 соединения открываются и закрываются одно за другим, а не 2 соединения открываются одновременно).

0
ответ дан 7 December 2019 в 14:36
поделиться

Помимо передачи DataContext в AddFiles в качестве параметра, вы также можете передать значение Connection одного DataContext другому DataContext. Это гарантирует, что другой DataContext имеет такое же соединение.

Каждый DataContext также имеет свойство Transaction, которое вы, вероятно, могли бы установить и передать вместо использования объекта TransactionScope.

1
ответ дан 7 December 2019 в 14:36
поделиться
Другие вопросы по тегам:

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