Баг в SqlQuery<T>
От: Wight Россия http://zyan.com.de
Дата: 29.04.09 09:04
Оценка:
Добрый день!
При использовании XML-extensions класс SqlQuery<T> некорректно генерирует запросы. То имя таблицы, то имя колонки берет не из TypeExtensions, а из названия класса или поля/свойства. Вот пример:

// csc /r:BLToolkit.3.dll /d:EXAMPLE1 bug.cs
// csc /r:BLToolkit.3.dll bug.cs

using System;
using System.IO;
using System.Text;
using BLToolkit.Data;
using BLToolkit.DataAccess;
using BLToolkit.Data.DataProvider;
using BLToolkit.Mapping;
using BLToolkit.Reflection.Extension;

public class Sample
{
    public class SomeClass
    {
        public int SomeValue { get; set; }
    }

    static void Main()
    {
        // для провайдера MsSql баг проявляется немного иначе
        DbManager.AddDataProvider(typeof(OdpDataProvider));
        DbManager.AddConnectionString("Odp", "Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=DBHost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=XE)));User Id=TestUser;Password=TestPassword;");

        // Должно быть:
        //
        // SELECT
        //        SOME_VALUE
        // FROM
        //        SOME_TABLE

#if EXAMPLE1
        // SELECT
        //        SOME_VALUE
        // FROM
        //        SomeClass

        using (var db = new DbManager())
        {
            db.MappingSchema.Extensions = TypeExtension.GetExtensions(Mappings);
            var query = new SqlQuery<SomeClass>();
            Console.WriteLine(query.GetSqlQueryInfo(db, "SelectAll").QueryText);
        }
#else
        // SELECT
        //        SomeValue
        // FROM
        //        SOME_TABLE

        using (var db = new DbManager())
        {
            var query = new SqlQuery<SomeClass>();
            query.Extensions = TypeExtension.GetExtensions(Mappings);
            Console.WriteLine(query.GetSqlQueryInfo(db, "SelectAll").QueryText);
        }
#endif
    }

    static Stream Mappings
    {
        get
        {
            return new MemoryStream(Encoding.UTF8.GetBytes(@"<?xml version='1.0' encoding='utf-8' ?>
                <Types xmlns='urn:schemas-bltoolkit-net:typeext' xmlns:da='urn:schemas-bltoolkit-net:dataaccess'>

                    <Type Name='SomeClass' da:TableName='SOME_TABLE'>
                        <Member Name='SomeValue' MapField='SOME_VALUE' />
                    </Type>

                </Types>"));
        }
    }
}


Правильного поведения можно добиться только если загрузить TypeExtensions одновременно в SqlQuery и в DbManager:

db.MappingSchema.Extensions = TypeExtension.GetExtensions(Mappings);
query.Extensions = db.MappingSchema.Extensions;


Это происходит из-за того, что в SqlQueryBase TypeExtensions иногда берутся из db.MappingSchema, а иногда из локальной схемы. Вот, например:

protected SqlQueryInfo CreateSelectAllSqlText(DbManager db, Type type)
{
    ObjectMapper  om    = db.MappingSchema.GetObjectMapper(type);
    StringBuilder sb    = new StringBuilder();
    SqlQueryInfo  query = new SqlQueryInfo(om);

    sb.Append("SELECT\n");

    foreach (MemberMapper mm in GetFieldList(om))
        sb.AppendFormat("\t{0},\n",
            db.DataProvider.Convert(mm.Name, ConvertType.NameToQueryField));

    sb.Remove(sb.Length - 2, 1);

    sb.AppendFormat("FROM\n\t{0}",
        db.DataProvider.Convert(GetTableName(type), ConvertType.NameToQueryTable));

    query.QueryText = sb.ToString();

    return query;
}


GetFieldList(om) берет названия свойств из db.MappingSchema.Extensions, а GetTableName(type) — из this.MappingSchema.Extensions. То же самое происходит во всех методах Create*SqlText.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.