我需要动态地将命名查询添加到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没有实现配置加载器和放大器的方法。来自hbm文件的sql-query元素。
答案 0 :(得分:1)
AddQueries方法将按如下方式实现,以“修复”Fluent NHibernate缺少Loader支持。诀窍是正确设置INativeSQLQueryReturn []值以包含从表列到实体属性的映射。它应该模仿HBM文件中sql-query的return元素的内容,其中定义了类(带命名空间)和属性映射(参见下面的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>
答案 1 :(得分:0)
我对此很新,但大多数参数看起来都可以从您在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这样的模糊属性,所以你不必这样做。
并不是说我希望它100%有效,但从这里可能更容易实现。