Linq-to-sql Compiled Query возвращает объект, НЕ принадлежащий представленному DataContext? - PullRequest
4 голосов
/ 18 марта 2010

Скомпилированный запрос:

   public static class Machines
   {
      public static readonly Func<OperationalDataContext, short, Machine>
          QueryMachineById = 
           CompiledQuery.Compile((OperationalDataContext db, short machineID) =>
           db.Machines.Where(m => m.MachineID == machineID).SingleOrDefault()
     );

     public static Machine GetMachineById(IUnitOfWork unitOfWork, short id)
     {
        Machine machine;

        // Old code (working)
        //var machineRepository = unitOfWork.GetRepository<Machine>();
        //machine = machineRepository.Find(m => m.MachineID == id).SingleOrDefault();

        // New code (making problems)
        machine = QueryMachineById(unitOfWork.DataContext, id);

        return machine;
     }

Похоже, скомпилированный запрос возвращает результат из другого контекста данных

  [TestMethod]
  public void GetMachinesTest()
  {
     using (var unitOfWork = IoC.Get<IUnitOfWork>())
     {
        // Compile Query
        var machine = Machines.GetMachineById(unitOfWork, 3);
        // In this unit of work everything works… 
        // Machine from repository (table) is equal to Machine from compile query.
     }

     using (var unitOfWork = IoC.Get<IUnitOfWork>())
     {
        var machineRepository = unitOfWork.GetRepository<Machine>();

        // Get From Repository
        var machineFromRepository = machineRepository.Find(m => m.MachineID == 2).SingleOrDefault();
        // Get From COmpiled Query
        var machine = Machines.GetMachineById(unitOfWork, 2);

        VerifyMachine(machineFromRepository, 2, "Machine 2", "222222", ...);
        VerifyMachine(machine, 2, "Machine 2", "222222", ...);

        Assert.AreSame(machineFromRepository, machine);       // FAIL
     }
  }

Если я запускаю другие (сложные) модульные тесты, я получаю как ожидалось: Была предпринята попытка присоединить или добавить объект, который не является новым, возможно, был загружен из другого DataContext.

Другая важная информация заключается в том, что этот тест находится под TransactionScope (но проблема появляется даже при отсутствии транзакции вокруг.)!

Я использую POCO, сопоставленные с БД с использованием XML.

UPDATE: Похоже, что следующая ссылка описывает похожую проблему (эта ошибка решена?): http://social.msdn.microsoft.com/Forums/en-US/linqprojectgeneral/thread/9bcffc2d-794e-4c4a-9e3e-cdc89dad0e38

Ответы [ 2 ]

1 голос
/ 22 марта 2010

Это ошибка, и она не будет исправлена.

Подобная проблема была описана в посте по ссылке ниже. Я пытался не использовать PK в скомпилированном запросе, как предложено, но получил ту же проблему. Таким образом, существует проблема с скомпилированными запросами, обходящими кеш.

Обходной путь для кэширования идентификационных данных сущностей LINQ to SQL и скомпилированного запроса?

1 голос
/ 18 марта 2010

Вы можете попробовать установить ObjectTrackingEnabled для контекста в false. Это помогло мне в этой же ситуации, но позже я включил его при обновлении и вставке записей.

DBDataContext.ObjectTrackingEnabled = false; // Read Only
...