Is there any consideration while comparing Enums in LINQ-to-NHibernate or LINQ?
In such a query:
var q = from l in session.Linq<Letter>()
where
letterTypeSearch == null ? true :
(l.LetterType.ToString() == letterTypeSearch)
l.LetterType is an Enum.
UPDATE
It seems that's impossible to compare Enums in current linq-to-nhibernate. While letterTypeSearch is a string containing a LetterType
instance that is ToString()
ed and LetterType
is inherited from int
, there 3 ways of comparisons:
1- Comparing in String
: It impossible because l.LetterType.ToString()
produces "(ArgumentOutOfRangeException): Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index, " error.
2- Comparing in Enum
(LetterType
) itself: It is impossible too because l.LetterType == LetterType.Internal
results in "(QueryException): Type mismatch in NHibernate.Criterion.SimpleExpression: LetterType expected type System.Int32, actual type Faraconesh.E开发者_StackOverflow社区nterpriseAppUnits.OfficeAutomation.BusinessEntities.LetterType,
" error.
3- Comparing in Int32
: Yet not possible, because Convert.ToInt32(l.LetterType)
generates "(NotImplementedException): The method ToInt32 is not implemented., " error.
So how can I compare Enums in LINQ-to-NHibernate? Is this problem specific to LINQ-to-NHibernate or all LINQ users have such a problem?
UPDATE2 here are class, enum and mapping (smmarized):
public class Letter
{
private LetterType _letterType;
public LetterType LetterType
{
set
{
_letterType = value;
}//end
get
{
return _letterType;
}//end
}
}
=========
public enum LetterType { Incoming = 0, Outgoing = 1, Internal = 2, }
=========
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-lazy="false">
<class
name="Faraconesh.EnterpriseAppUnits.OfficeAutomation.BusinessEntities.Letter,Faraconesh.EnterpriseAppUnits.OfficeAutomation.BusinessEntities"
table="OfficeAutomation_Letter">
<property
name="LetterType" column="LetterType"
type="int" update="true" insert="true" access="property"
not-null="true"/>
</class>
</hibernate-mapping>
You have mapped the enum as type="int"
which causes the error, probably because there are no implicit conversions to and from int. If you drop the type attribute, the enum will be mapped to an int value in the database and the Linq queries will work.
Note also that in your property mapping every attribute except name and type are unnecessary as they specify the default values. "Name" is the only required attribute on a property mapping, see section property in the reference documentation.
<property name="LetterType" />
Using the latest (2.1.2GA) version of NHibernate.Linq, which is available from the NHibernate Core download link on nhforge.org, the following queries with enums work as expected.
var q = from l in session.Linq<Letter>()
where l. LetterType == LetterType.A4
select l;
var result = q.ToList<Letter>();
LetterType? ltype = LetterType.A4;
q = from l in session.Linq<Letter>()
select l;
if (code != null) {
q = q.Where( l => l.LetterType == ltype.Value );
}
result = q.ToList<Letter>();
However, this form of the last query will not work if ltype is null as the query parser will still try to use ltype.Value.
q = from l in session.Linq<Letter>()
where ltype != null && l => l.LetterType == ltype.Value
select l;
result = q.ToList<Letter>();
If I were you, I create a Dot net Enum with these nhibernate Enum and then compare them with dot net equals.
精彩评论