我有2个名为Order和Orderrow的类。我使用NHibernate来加入它。
当运行NUnit来测试查询时,我得到了一个ADOException:
Logica.NHibernate.Tests.NHibernateTest.SelectAllOrdersFromSupplierNamedKnorrTest:
NHibernate.ADOException : could not execute query
[ SELECT this_.OrderId as OrderId1_1_, this_.CreatedAt as CreatedAt1_1_, this_.ShippedAt as ShippedAt1_1_, this_.ContactId as ContactId1_1_, customer2_.ContactId as ContactId0_0_, customer2_.LastName as LastName0_0_, customer2_.Initials as Initials0_0_, customer2_.Address as Address0_0_, customer2_.City as City0_0_, customer2_.Country as Country0_0_ FROM Order this_ inner join Contact customer2_ on this_.ContactId=customer2_.ContactId ]
[SQL: SELECT this_.OrderId as OrderId1_1_, this_.CreatedAt as CreatedAt1_1_, this_.ShippedAt as ShippedAt1_1_, this_.ContactId as ContactId1_1_, customer2_.ContactId as ContactId0_0_, customer2_.LastName as LastName0_0_, customer2_.Initials as Initials0_0_, customer2_.Address as Address0_0_, customer2_.City as City0_0_, customer2_.Country as Country0_0_ FROM Order this_ inner join Contact customer2_ on this_.ContactId=customer2_.ContactId]
----> System.Data.SqlClient.SqlException : Incorrect syntax near the keyword 'Order'.
在分析由NHibernate创建的SQL时,我注意到Order类正在破坏SQL语句,因为ORDER BY是SQL中的内部关键字。
这是NHibernate中创建的SQL:
SELECT this_.OrderId as OrderId1_1_, this_.CreatedAt as CreatedAt1_1_, this_.ShippedAt as ShippedAt1_1_, this_.ContactId as ContactId1_1_, customer2_.ContactId as ContactId0_0_, customer2_.LastName as LastName0_0_, customer2_.Initials as Initials0_0_, customer2_.Address as Address0_0_, customer2_.City as City0_0_, customer2_.Country as Country0_0_ FROM Order this_ inner join Contact customer2_ on this_.ContactId=customer2_.ContactId
我在SQL Server 2008管理工作室中对此进行了更改,如下所示:
SELECT this_.OrderId as OrderId1_1_, this_.CreatedAt as CreatedAt1_1_, this_.ShippedAt as ShippedAt1_1_, this_.ContactId as ContactId1_1_, customer2_.ContactId as ContactId0_0_, customer2_.LastName as LastName0_0_, customer2_.Initials as Initials0_0_, customer2_.Address as Address0_0_, customer2_.City as City0_0_, customer2_.Country as Country0_0_ FROM [Order] this_ inner join Contact customer2_ on this_.ContactId=customer2_.ContactId`
我在表名称Order中加了括号(就像这样:[Order])并且它是固定的。
但是如何在NHibernate中修复此问题呢?是否有映射XML文件指令才能完成此操作?
(使用VS2008 SP1,SQL Server 2008 SP1,NHibernate 2.0.1 GA)
答案 0 :(得分:6)
参见this,“5.3.SQL引用标识符”部分。你基本上需要这个:
<class name="Order" table="`Order`">
答案 1 :(得分:6)
我认为如果你在映射文件中放置引号(“[”和“]”在SQL Server中,或者你的数据库支持的任何引号),hibernate会在生成查询时引用对象名称。
(也许发布您的地图文件,我们可以看看)
答案 2 :(得分:5)
在Fluent NHibernate中,添加
.Column("`Order`");
到您的映射以修复此错误。
答案 3 :(得分:0)
使用约定时,您可以添加以下内容:
public class TableNameConvention
: IClassConvention, IClassConventionAcceptance
{
public void Accept(IAcceptanceCriteria<IClassInspector> criteria)
{
criteria.Expect(x => Check(x));
}
private bool Check(IClassInspector x)
{
return String.IsNullOrWhiteSpace(x.TableName) || x.TableName.Equals("`{0}`".Args(x.EntityType.Name));
}
public void Apply(IClassInstance instance)
{
instance.Table("`" + instance.EntityType.Name + "`");
}
}
要修复保留表名称和保留列名称(例如“From”)的问题,可以使用以下内容:
public class ColumnNameConvention : IPropertyConvention, IPropertyConventionAcceptance
{
public void Apply(IPropertyInstance instance)
{
instance.Column("`" + instance.Property.Name + "`");
}
public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
{
criteria.Expect(c => Check(c));
}
private bool Check(IPropertyInspector inspector)
{
//walkaround:
//this convention causes problems with Components - creates columns like Issue`Id` so we apply it only to entities
var type = inspector.EntityType;
if (!(type.IsSubclassOf(typeof (Entity)) || type.IsSubclassOf(typeof (GlossaryEntity))))
{
return false;
}
return true;
}
}