我一直在尝试按照 Hendry Luk 的计算属性解决方案在我的持久层中创建一个计算属性。
我可以使用 linq 查询从数据库中选择值:
var result = from parcel in Repository.Query();
当我尝试对所选结果执行 where 时,出现无法解析属性错误。
这是我的代码的样子。
我的模型:
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<Common1, string>> CalculatedDisplayExpression = x => ("Common 1 Display: " + x.Id + " - " + x.Name);
public static readonly Expression<Func<Common1, string>> CalculatedDisplayExpression = x => (x.Id + "");
private static readonly Func<Common1, string> 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<Common1>
{
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<T, TResult> : BaseHqlGeneratorForProperty
{
public static void Register(ILinqToHqlGeneratorsRegistry registry, Expression<Func<T, TResult>> property, Expression<Func<T, TResult>> calculationExp)
{
registry.RegisterGenerator(ReflectionHelper.GetProperty(property), new CalculatedPropertyGenerator<T, TResult> { _calculationExp = calculationExp });
}
private CalculatedPropertyGenerator() { }
private Expression<Func<T, TResult>> _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<MsSql2008Dialect>();
db.Driver<SqlClientDriver>();
db.LogSqlInConsole = true;
db.IsolationLevel = System.Data.IsolationLevel.ReadCommitted;
})
.AddDeserializedMapping(GetMappings(), null);
CalculatedPropertyGenerator<Common1, string>.Register(registry, x => x.Display, Common1.CalculatedDisplayExpression);
// registry.RegisterGenerator(ReflectionHelper.GetProperty<Common1, string>(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<ICommon> commons = session.Query<ICommon>();//.Where(x => x.Display.Contains("Common1 #7"));
var common1 = session.Query<Common1>().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();
}
}
}
}