Re[2]: Linq bug?
От: Ziaw Россия  
Дата: 02.06.10 16:53
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Ну, или как-то по другому сделай так чтобы можно было воспроизвести ошибку на чужой машине.


using System;
using System.Console;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Expressions;
using Nemerle.Data.Linq;
using BLToolkit.Data;
using BLToolkit.Data.Linq;

public class Data
{
   public Id : Guid {get;set;}
}
    
module Program
{
    Main() : void
    {
        def toExpr(e : Expression[Func[Data, bool]]) { e }
        
        def id1 = Guid.NewGuid();
        def id2 = Guid.NewGuid();
        
        def e1 = toExpr(d => d.Id == id1);
        def e2 = toExpr(d => d.Id == id2);
        
        // корень проблемы:
        WriteLine($"Тулкит думает, что $e1 == $e2");
        // продемонстрировать напрямую не получается, потому, что метод сравнения в internal классе
        // ExpressionHelper.Compare(e1, e2) вернет true, поскольку различаются они только значением константы, 
        // а тулкит по каким-то причинам не сравнивает значения констант для Guid (скорее всего такая ситуация не встречается в C#)
        
        // воспроизведение:
        // Нужен sqlserver и база в которой запущено create table Data (Id uniqueidentifier)
        DbTest(@"data source=.\SQLEXPRESS;Integrated Security=true;database=TestDb");
    }

    DbTest(connString : string) : void
    {
        using (conn = SqlConnection(connString), db = DbManager(conn))
        {
            _ = db.BeginTransaction(); // rollback
            
            def d1 = Data(); d1.Id = Guid.NewGuid();
            def d2 = Data(); d2.Id = Guid.NewGuid();
            
            _ = db.Insert(d1);
            _ = db.Insert(d2);
            
            def id1 = d1.Id; // если в експрешен отдать d1.Id константы не будет и тест пройдет
            def id2 = d2.Id;
            
            _ =  db.GetTable.[Data]().Single(d => d.Id == id1);
            // вот тут тулкит считает, что ему передали тот же самый экспрешен и выполняет закешированный запрос
            def test = db.GetTable.[Data]().Single(d => d.Id == id2); 
            
            if (test.Id == d2.Id) // test.Id в данном случае будет равен d1.Id
                WriteLine("Ok")
            else
                WriteLine("Error");
        }
    }
}
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.