我有一个支持基于多个标识符查询的数据源。这些标识符由IIdentifier类抽象,该类包装查询的类型和值。在我的NHibernate DAO中,我有以下方法。
public IEnumerable<ICustomerProfileAttribute> GetCustomerProfileAttributes(
IIdentifier<CustomerIdentifierTypeEnum> identifier, IEnumerable<string> attributeNames)
{
IList<ICustomerProfileAttribute> customerProfileAttributes = new List<ICustomerProfileAttribute>();
ICustomerProfile customerProfileAlias = null;
ICustomerProfileAttribute customerProfileAttributeAlias = null;
IEntityTypeAttribute entityTypeAttribute = null;
IAttribute attributeAlias = null;
Expression<Func<bool>> findCustomerProfileQuery;
// I would like to replace the switch with something like this:
// = FindCustomerProfileExpressionFactory.Get(customerProfileAlias, identifier);
switch (identifier.IdentifierType)
{
case CustomerIdentifierTypeEnum.CustomerNumber:
findCustomerProfileQuery = () => customerProfileAlias.CustomerNumber == identifier.Value.ToString();
break;
case CustomerIdentifierTypeEnum.WebAccount:
findCustomerProfileQuery = () => customerProfileAlias.WebAccountId == (long)identifier.Value;
break;
case CustomerIdentifierTypeEnum.WebLogin:
findCustomerProfileQuery = () => customerProfileAlias.LoginEmailAddress == identifier.Value.ToString();
break;
default:
throw new NotImplementedException(String.Format("lookup of customer profiles using {0} is not supported", identifier.IdentifierType));
}
return Session.QueryOver(() => customerProfileAttributeAlias)
.JoinAlias(() => customerProfileAttributeAlias.CustomerProfile, () => customerProfileAlias,
JoinType.LeftOuterJoin)
.Where(findCustomerProfileQuery)
.JoinAlias(() => customerProfileAttributeAlias.EntityTypeAttribute, () => entityTypeAttribute,
JoinType.LeftOuterJoin)
.JoinAlias(() => entityTypeAttribute.Attribute, () => attributeAlias, JoinType.LeftOuterJoin)
.Where(Restrictions.On(() => attributeAlias.Name).IsIn(attributeNames.ToArray()))
.List<ICustomerProfileAttribute>();
}
我想将switch语句解压缩到工厂类中,因为它在我的应用程序的其他几个部分中很有用。我尝试了以下方法:
class FindCustomerProfileExpressionFactory
{
static public Expression<Func<bool>> Get(ICustomerProfile profile, IIdentifier<CustomerIdentifierTypeEnum> identifier)
{
switch (identifier.IdentifierType)
{
case CustomerIdentifierTypeEnum.CustomerNumber:
return () => customerProfileAlias.CustomerNumber == identifier.Value.ToString();
...
但是,通过引用工厂类,我将局部变量别名化为lambda表达式,从而导致以下错误:
NHibernate.QueryException: could not resolve property: profile of: CustomerProfile.Domain.CustomerProfileAttribute
有没有办法生成一个引用局部变量的表达式?我可以使用带有Where子句的参数化表达式吗?还有其他解决方案吗?
答案 0 :(得分:1)
我最终找到了答案。似乎NHibernate在其代码中以某种方式使用QueryOver表达式中的变量名称。我在工厂中更改了参数名称以匹配方法中的变量名称,并且它有效!
答案 1 :(得分:0)
QueryOver不是LINQ,因此它在接受的表达式中受到更多限制。
除非你真的需要那些左连接(我无法分辨),否则我可能会使用LINQ。它会不那么复杂。