Linq-to-sql Compiled Query returning object NOT belonging to submitted DataContext
- by Vladimir Kojic
Compiled query:
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;
}
It looks like compiled query is caching Machine object and returning the same object even if query is called from new DataContext (I’m disposing DataContext in the service but I’m getting Machine from previous DataContext).
I use POCOs and XML mapping.
Revised:
It looks like compiled query is returning result from new data context and it is not using the one that I passed in compiled-query. Therefore I can not reuse returned object and link it to another object obtained from datacontext thru non compiled queries.
[TestMethod]
public void GetMachinesTest()
{
// Test Preparation (not important)
using (var unitOfWork = IoC.Get<IUnitOfWork>())
{
var machineRepository = unitOfWork.GetRepository<Machine>();
// GET ALL
List<Machine> list = machineRepository.FindAll().ToList<Machine>();
VerifyIntegratedMachine(list[2], 3, "Machine 3", "333333", "G300PET", "MachineIconC.xaml", false, true, LicenseType.Licensed, "10.0.97.3", "10.0.97.3", 0);
var machine = Machines.GetMachineById(unitOfWork, 3);
Assert.AreSame(list[2], machine); // PASS !!!!
}
using (var unitOfWork = IoC.Get<IUnitOfWork>())
{
var machineRepository = unitOfWork.GetRepository<Machine>();
// GET ALL
List<Machine> list = machineRepository.FindAll().ToList<Machine>();
VerifyIntegratedMachine(list[2], 3, "Machine 3", "333333", "G300PET", "MachineIconC.xaml", false, true, LicenseType.Licensed, "10.0.97.3", "10.0.97.3", 0);
var machine = Machines.GetMachineById(unitOfWork, 3);
Assert.AreSame(list[2], machine); // FAIL !!!!
}
}
If I run other (complex) unit tests I'm getting as expected:
An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext.