2016-11-08 38 views
1

使用NHibernate和Oracle,我在订购条件时遇到了一个问题。 说我已经得到了这些实体(及其相应的数据库类型):NHibernate在Oracle中铸造字符串参数

public class Contact 
{ 
    public virtual int PrimaryKey { get; set; } // number(38,0) NOT NULL 
    public virtual string Name { get; set; } // nvarchar2(max) NULL 
    public virtual int? CompanyFk { get; set; } // number(38,0) NULL 
    public virtual Company Company { get; set; } 
} 
public class Company 
{ 
    public virtual int PrimaryKey { get; set; } // number(38,0) NOT NULL 
    public virtual string Name { get; set; } // nvarchar2(max) NULL 
} 

以常规的方式映射,使得使用LINQ,我可以查询这样的:

var boeingEmployees = Context.Contacts.Where(c => c.Company.Name == "Boeing"); 

麻烦的开始,如果我做这样的事情:

var query = Context.Contacts.OrderBy(c => c.Company == null ? null : c.Company.Name); 

在这种情况下,也许上面是愚蠢的,但我有多个情况下,我可能有一个条件排序依据。所以NHibernate翻译这个是这样的:

SELECT CONTACT.PRIMARYKEY, CONTACT.NAME, CONTACT.COMPANYFK 
FROM CONTACT 
LEFT OUTER JOIN COMPANY ON CONTACT.COMPANYFK = COMPANY.PRIMARYKEY 
ORDER BY CAST(CASE WHEN CONTACT.COMPANYFK IS NULL THEN :p0 ELSE COMPANY.NAME END AS NVARCHAR(255)) ASC; 

参数p0为空。或者我可以让它成为string.Empty或“abc”。无论字符串是什么,参数本身都是varchar2类型,而COMPANY.NAME是nvarchar2。此Oracle异常得到投掷:

ORA-12704:字符集不匹配

如果我摆弄SQL,以便排序依据是这样的,

ORDER BY CASE WHEN CONTACT.COMPANYFK IS NULL THEN CAST(:p0 AS NVARCHAR2(255)) ELSE COMPANY.NAME END ASC 

那么查询工作正常。但显然,这是NHibernate生成的代码,我不能(我认为)在实践中真正改变它。

因此,少数与NHibernate和Oracle合作的问题......处理这个问题的最佳方法是什么?有没有方法来投射参数?或者在NHibernate中设置一个默认的字符串字符集?

谢谢

+0

可能的重复[C#??运算符和ora-12704:字符集不匹配](http://stackoverflow.com/questions/28082826/c-sharp-operator-and-ora-12704-character-set-mismatch) –

+0

@ shA.t是的,它看起来就像Select和OrderBy中的问题一样。不同case语句中的数据类型不匹配。 – ZrSiO4

回答

0

在您的映射中使用AnsiString特定属性。那么你将不会有这些铸件。

+0

似乎有点倒退,不得不改变数据库以适应这种奇怪的怪癖。另外为了传统目的,我需要保持数据库不变。 – ZrSiO4

+0

我从来没有说过你应该改变数据库。只需更改映射。 –