Как класс NamedSQLQueryDefinition можно динамически использовать как эквивалент SQL-запроса? - PullRequest
1 голос
/ 05 августа 2010

Мне нужно динамически добавлять именованные запросы в объект конфигурации NHibernate. Поисковые системы возвращают несколько обращений, ссылающихся на NamedSQLQueryDefinition или NamedQueryDefinition. Ниже то, что я пытаюсь сделать. Я не знаю, что предоставить конструктору NamedSQLQueryDefinition для успешного создания запроса. Кто-нибудь может предоставить пример того, как правильно создать новое NamedSQLQueryDefinition? Спасибо !!

Инициализатор сеанса:

    private static ISessionFactory CreateSessionFactory()
    {
        var configuration = new Configuration();

        return Fluently.Configure(configuration.Configure())
            .ExposeConfiguration(AddQueries)
            .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Program>())
            .Mappings(m => m.HbmMappings.AddFromAssemblyOf<Program>())
            .BuildConfiguration()
            .BuildSessionFactory();
    }

AddQueries будет выглядеть примерно так:

    private static void AddQueries(Configuration cfg)
    {
        var nameQuery = new NamedSQLQueryDefinition("exec pr_GETCustomer ?", ...)

        cfg.NamedSQLQueries.Add("pr_GETCustomer", nameQuery);
        var cust = cfg.GetClassMapping(typeof (Customer));

        cust.LoaderName = "pr_GETCustomer";
    }

PS: я пробую этот маршрут, потому что Fluent NHibernate не реализует способ настройки элементов загрузчика и sql-запроса из файла hbm.

Ответы [ 2 ]

1 голос
/ 17 августа 2010

Метод AddQueries будет реализован следующим образом, чтобы «исправить» отсутствие поддержки Loader в Fluent NHibernate.Хитрость заключается в том, чтобы правильно настроить значение INativeSQLQueryReturn [], чтобы оно содержало отображение столбцов таблицы на свойства сущности.Он должен имитировать содержимое возвращаемого элемента sql-запроса в файле HBM, где определены класс (с пространством имен) и сопоставления свойств (см. XML ниже).Спасибо @jimbobmcgee за то, что я начал работать в этом направлении!

private static void AddQueries(Configuration cfg)
{
    var namedQuery = new NamedSQLQueryDefinition(
        "exec dbo.pr_GETCustomers @CustomerID=?",
        new INativeSQLQueryReturn[]
            {
                new NativeSQLQueryRootReturn(
                    "Customers",
                    "VehicleInfo.Entities.Customers",
                    new Dictionary<string, string[]>
                        {
                                    {"CustomerID", new[] {"CustomerID"}},
                                    {"CompanyName", new[] {"CompanyName"}}
                    },
                    LockMode.Read)
            },
        new List<string> { "dbo.Customers" },
        true,
        null,
        15,
        1000,
        FlushMode.Auto,
        CacheMode.Normal,
        false,
        "",
        null,
        true);

    cfg.NamedSQLQueries.Add("pr_GETCustomers", namedQuery);
    var cust = cfg.GetClassMapping(typeof(Customers));

    cust.LoaderName = "pr_GETCustomers";
}

Образец файла HBM, который делает то же самое:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
    default-access="property" auto-import="true" 
    default-cascade="none" default-lazy="true">
    <class xmlns="urn:nhibernate-mapping-2.2"
        mutable="true" name="VehicleInfo.Entities.Customers, VehicleInfo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" table="Customers">
        <id name="CustomerID" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
            <column name="CustomerID" />
            <generator class="assigned" />
        </id>

        <property name="CompanyName" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
            <column name="CompanyName" />
        </property>

        <loader query-ref="pr_GETCustomers"/>

        <sql-insert callable="true" check="none">exec dbo.pr_INSERTCustomers @CompanyName=?, @CustomerID=?</sql-insert>
        <sql-update callable="true" check="none">exec dbo.pr_UPDATECustomers @CompanyName=?, @CustomerID=?</sql-update>
        <sql-delete callable="true" check="none">exec dbo.pr_DELETECustomers @CustomerID=?</sql-delete>
    </class>
    <sql-query name="pr_GETCustomers">
        <return alias="cust" class="VehicleInfo.Entities.Customers, VehicleInfo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
            <return-property name="CustomerID" column="CustomerID"></return-property>
            <return-property name="CompanyName" column="CompanyName"></return-property>
        </return>
        exec dbo.pr_GETCustomers @CustomerID=?
    </sql-query>
</hibernate-mapping>
0 голосов
/ 10 августа 2010

Я довольно новичок в этом, но большинство параметров выглядят определяемыми из атрибутов, которые вы можете предоставить в файле HBM.Тем не менее, я не слишком уверен, что такое QuerySpaces.Самое близкое, что я думаю к тому, что вы пытаетесь достичь, - это использовать следующее (не проверено):

ISQLQuery q = session.CreateSQLQuery("exec pr_GETCustomer :p1");

if (q is SqlQueryImpl)
{
    IDictionary<string, TypedValue> namedParams = new Dictionary<string, TypedValue>();
    namedParams.Add("p1", new TypedValue(NHibernateUtil.Int32, 12345);

    IDictionary<string, string> paramTypes = new Dictionary<string, string>();

    NativeSQLQuerySpecification spec = 
        (q as SqlQueryImpl).GenerateQuerySpecification(namedParams);

    NativeSQLQueryDefiniton def = new NativeSQLQueryDefiniton(
        spec.QueryString,
        spec.SqlQueryReturns,
        spec.QuerySpaces,
        false,
        null,
        -1,
        -1,
        FlushMode.Never,
        CacheMode.Normal,
        true,
        "blah",
        paramTypes,
        false
    );
}

Очевидно, мне не нравится приведение к SqlQueryImpl.Я надеюсь, что, как только один из нас сделает это один раз, непонятные свойства, такие как querySpaces, могут быть поняты, так что вам не придется это делать.быть более достижимым отсюда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...