3

Hendry Luk の計算されたプロパティのソリューションに従って、永続化レイヤーに計算されたプロパティを作成しようとしてい ます。

linq クエリを使用して DB から値を選択できます。

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); } }
        }
    }

My Interface を実装するモデル:

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();
            }
        }
    }
}
4

2 に答える 2

3

のように、SessionProvider クラスに登録します。

configuration.LinqToHqlGeneratorsRegistry<MyLinqToHqlGeneratorsRegistry>(); 

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<Common1, string>.Register(this, x => x.Display, Common1.CalculatedDisplayExpression);
        }
    }
}
于 2013-01-09T18:35:57.220 に答える