在nhibernate中的Linq-ing计算属性无法解析属性Error

我一直试图通过遵循Hendry Luk的计算属性解决方案在我的持久层中创建一个计算属性 。

我可以使用linq查询从数据库中选择值:

var result = from parcel in Repository.Query(); 

当我尝试在所选结果上执行某个位置时,我得到一个无法解决属性错误。

这是我的代码的样子。

我的型号:

  namespace ConsoleApplication14 { using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; public class Common1 : ICommon { public virtual int Id { get; set; } public virtual string Name { get; set; } //public static readonly Expression<Func> CalculatedDisplayExpression = x => ("Common 1 Display: " + x.Id + " - " + x.Name); public static readonly Expression<Func> CalculatedDisplayExpression = x => (x.Id + ""); private static readonly Func CalculateDisplay = CalculatedDisplayExpression.Compile(); public virtual string Display { get { return CalculateDisplay(this); } } } } 

我的界面模型实现:

 namespace ConsoleApplication14 { using System; using System.Collections.Generic; using System.Linq; using System.Text;`enter code here` public interface ICommon { int Id { get; set; } string Name { get; set; } string Display { get; } } } 

模型的映射

 namespace ConsoleApplication14 { using System; using System.Collections.Generic; using System.Linq; using System.Text; using NHibernate.Mapping.ByCode; using NHibernate.Mapping.ByCode.Conformist; public class Common1Map : ClassMapping { public Common1Map() { Id(x => x.Id, map => map.Generator(Generators.Native)); Property(x => x.Name); } } } namespace ConsoleApplication14 { using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Reflection; using System.Text; using NHibernate.Hql.Ast; using NHibernate.Linq; using NHibernate.Linq.Functions; using NHibernate.Linq.Visitors; public class CalculatedPropertyGenerator : BaseHqlGeneratorForProperty { public static void Register(ILinqToHqlGeneratorsRegistry registry, Expression<Func> property, Expression<Func> calculationExp) { registry.RegisterGenerator(ReflectionHelper.GetProperty(property), new CalculatedPropertyGenerator { _calculationExp = calculationExp }); } private CalculatedPropertyGenerator() { } private Expression<Func> _calculationExp; public override HqlTreeNode BuildHql(MemberInfo member, Expression expression, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor) { return visitor.Visit(_calculationExp); } } } namespace ConsoleApplication14 { using System; using System.Collections.Generic; using System.Linq; using System.Text; using NHibernate; using NHibernate.Cfg; using NHibernate.Cfg.MappingSchema; using NHibernate.Dialect; using NHibernate.Driver; using NHibernate.Tool.hbm2ddl; using NHibernate.Mapping.ByCode; using NHibernate.Mapping; using Iesi.Collections.Generic; using System.Reflection; using NHibernate.Linq.Functions; using NHibernate.Linq; public class SessionProvider { private static ISessionFactory sessionFactory; public static SessionProvider Instance { get; private set; } //DefaultLinqToHqlGeneratorsRegistry registry = new DefaultLinqToHqlGeneratorsRegistry(); ILinqToHqlGeneratorsRegistry registry = new DefaultLinqToHqlGeneratorsRegistry(); static SessionProvider() { var provider = new SessionProvider(); provider.Initialize(); Instance = provider; } private SessionProvider() { } private void Initialize() { const string connString = "server=(local)\\mssql2008;database=Common;integrated security=sspi"; Configuration configuration = new Configuration(); configuration .DataBaseIntegration(db => { db.ConnectionString = connString; db.Dialect(); db.Driver(); db.LogSqlInConsole = true; db.IsolationLevel = System.Data.IsolationLevel.ReadCommitted; }) .AddDeserializedMapping(GetMappings(), null); CalculatedPropertyGenerator.Register(registry, x => x.Display, Common1.CalculatedDisplayExpression); // registry.RegisterGenerator(ReflectionHelper.GetProperty(x => x.Display), new CalculatedPropertyGenerator()); var exporter = new SchemaExport(configuration); exporter.Execute(true, true, false); sessionFactory = configuration.BuildSessionFactory(); } private HbmMapping GetMappings() { ModelMapper mapper = new ModelMapper(); mapper.AddMappings(Assembly.GetAssembly(typeof(Common1Map)).GetExportedTypes()); HbmMapping mappings = mapper.CompileMappingForAllExplicitlyAddedEntities(); return mappings; } public ISession OpenSession() { return sessionFactory.OpenSession(); } } } 

客户:

 namespace ConsoleApplication14 { using System; using System.Collections.Generic; using System.Linq; using System.Text; using NHibernate; using NHibernate.Linq; using NHibernate.Linq.Functions; public class Tester { private ILinqToHqlGeneratorsRegistry registry = new DefaultLinqToHqlGeneratorsRegistry(); public void Go() { using (ISession session = SessionProvider.Instance.OpenSession()) { CreateData(session); IQueryable commons = session.Query();//.Where(x => x.Display.Contains("Common1 #7")); var common1 = session.Query().Where(x => x.Display.Contains("Common1 #7")); foreach(var common in commons) { Console.WriteLine(common.Display); } } } private void CreateData(ISession session) { using (ITransaction tx = session.BeginTransaction()) { for (int i = 0; i < 10; i++) { session.SaveOrUpdate(new Common1() { Name = "Common1 #" + i }); } tx.Commit(); } } } } 

您需要从DefaultLinqToHqlGeneratorsRegistry派生一个类。 在其构造函数中添加注册逻辑(将“this”传递给CalculatedPropertyGenerator <>。Register())。 然后使用以下命令注册NHibernate配置的类:

 cfg.LinqToHqlGeneratorsRegistry(); 

在SessionProvider类中注册,就像

 configuration.LinqToHqlGeneratorsRegistry(); 

MyLinqToHQLGeneratorRegistry实现如下所示

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using NHibernate.Linq.Functions; using NHibernate.Linq; namespace ConsoleApplication14 { public class MyLinqToHqlGeneratorsRegistry : DefaultLinqToHqlGeneratorsRegistry { public MyLinqToHqlGeneratorsRegistry() : base() { CalculatedPropertyGenerator.Register(this, x => x.Display, Common1.CalculatedDisplayExpression); } } }