需要帮助将SQL转换为条件API
问题描述:
我有一个NHibernate应用程序,当前使用SQL Server用户定义函数。我想避免不得不调用这个函数,而是使用NH标准API来表达它的逻辑。不幸的是,我很难将NH文档中的标准示例应用到我的特例中。所以我转向这个网站寻求帮助。需要帮助将SQL转换为条件API
这是功能。它接受一个字符串参数并返回一个表。该函数在相同的两个表格之间执行3个连接,但使用不同的连接标准,然后合并结果。
任何提示将不胜感激。提前致谢!
编辑:这是针对NH 2.1
编辑:在接受答案的注释指出,转换是不可能的,这是正确的答案。
CREATE FUNCTION dbo.GetRevisionText
(
@LangId NVARCHAR(16)
)
RETURNS TABLE
AS
RETURN
(
SELECT r.RevisionId,
COALESCE(lp1.Title, lp2.Title, lp3.Title) Title,
COALESCE(lp1.Description, lp2.Description, lp3.Description) Description
FROM Revision r
LEFT JOIN LocalizedProperty lp1
ON lp1.RevisionId = r.RevisionId
AND lp1.LanguageId = @LangId
LEFT JOIN LocalizedProperty lp2
ON lp2.RevisionId = r.RevisionId
AND lp2.LanguageId = LEFT(@LangId, 2)
LEFT JOIN LocalizedProperty lp3
ON lp3.RevisionId = r.RevisionId
AND lp3.LanguageId = r.DefaultPropertiesLanguage
);
这里是所涉及的3类的映射:
<class name="Revision">
<id name="RevisionId" type="Guid">
<generator class="assigned"/>
</id>
<set name="LocalizedProperties" inverse="true" lazy="true" cascade="all-delete-orphan">
<key column="RevisionId"/>
<one-to-many class="LocalizedProperty"/>
</set>
<many-to-one name="DefaultPropertiesLanguage" class="Language" not-null="true"/>
</class>
<class name="Language">
<id name="LanguageId" type="String" length="16">
<generator class="assigned"/>
</id>
<property name="Lcid" type="Int32" unique="true" not-null="true"/>
</class>
<class name="LocalizedProperty" mutable="false">
<composite-id>
<key-many-to-one name="Revision" class="Revision" column="RevisionId"/>
<key-many-to-one name="Language" class="Language" column="LanguageId"/>
</composite-id>
<property name="Title" type="String" length="200" not-null="true"/>
<property name="Description" type="String" length="1500" not-null="false"/>
</class>
答
这可能做的工作(NH 1.2):但是,这并不产生ANSI语法
var crit = nhSes.CreateCriteria(typeof(Revision), "r")
.SetProjection(
Projections.SqlProjection(@"r.RevisionId as rid,
COALESCE(lp1.Title, lp2.Title, lp3.Title) as Title,
COALESCE(lp1.Description, lp2.Description, lp3.Description) as Description", new[] {"rid", "Title", "Description"}, new[] {NHibernateUtil.Guid, NHibernateUtil.String,NHibernateUtil.String})
);
crit.CreateCriteria("LocalizedProperty", "lp1", JoinType.InnerJoin);
crit.CreateCriteria("LocalizedProperty", "lp2", JoinType.InnerJoin);
crit.CreateCriteria("LocalizedProperty", "lp3", JoinType.InnerJoin);
crit.Add(Expression.Eq("lp1.LanguageId", langId));
crit.Add(Expression.Sql("lp2.LanguageId = LEFT(:LangId, 2)", langId, NHibernateUtil.String));
crit.Add(Expression.EqProperty("lp3.LanguageId", "r.DefaultPropertiesLanguage"));
记加入但将约束置于WHERE子句中。我真的不认为这是一个问题,你正在做一个内部连接,而不是一个外部连接。
另外我现在不记得在Expression.Sql
上的正确参数符号。 我把它定义为:LangId
虽然它也可能是@LangId
旁注:你可以看到,虽然这是一个标准的查询它只是一堆SQL语句的拆分所以符合标准的API;你确定这是你需要的吗?
感谢您的帮助,它给了我一个腿。不幸的是,它不工作:(NH抱怨“重复关联路径:LocalizedProperty”。我目前正在调查映射的第二和第三LocalizedProperty别名与视图... – 2009-12-01 02:32:45
你试过使用 crit.CreateAlias(“LocalizedProperty” ,“lp1”); 它可能会抛出相同的错误,但你没有什么可以松动的 – Jaguar 2009-12-01 08:52:25
就好像它不支持...检查http://nhjira.koah.net/browse/NH-2016 .. 。如果你真的想将数据库中的代码移植到你的应用程序中,ISQLQuery是唯一的方法 – Jaguar 2009-12-01 09:03:28