1

コンポーネントごとにNHibernate Linqでクエリを実行したい。コンポーネントには、オーバーライド Equalsに含まれていないDate プロパティが含まれています。平等を求めるときに Date プロパティをスキップしたいだけです。現時点では、Date プロパティが Address クラスの ctor に設定されているため、クエリは0 行を返します。これが値オブジェクトの概念に違反していることはわかっていますが、以下のコードが正しく機能しない理由を知りたいだけです。

THE QUERY ご覧のとおり、Date プロパティはクエリに含まれています

select user0_.Id     as Id0_,
       user0_.Name   as Name0_,
       user0_.Number as Number0_,
       user0_.Date   as Date0_
from   test1 user0_
where  (user0_.Number = 1 /* @p0 */
        and user0_.Date = '2013-01-28T14:29:47.00' /* @p1 */)

主要

class Program
    {
        private static ISessionFactory _sessionFactory;

        private static void CreateSessionFactory()
        {
            FluentConfiguration config = Fluently
                .Configure(new Configuration().Configure())
                .Mappings(m => m.FluentMappings.AddFromAssemblyOf<UserMap>());
            new SchemaExport(config.BuildConfiguration()).Create(false, true);
            _sessionFactory = config.BuildSessionFactory();
        }

        [STAThread]
        static void Main(string[] args)
        {
            CreateSessionFactory();

            using (var session = _sessionFactory.OpenSession())
            using (var tx = session.BeginTransaction())
            {
                var user = new User()
                {
                    Name = "Nik",
                    Address = new Address(1)
                };
                session.Save(user);
                tx.Commit();
            }

            using (var session = _sessionFactory.OpenSession())
            using (var tx = session.BeginTransaction())
            {
                session.Query<User>().Where(x => x.Address == new Address(1)).Single();
                tx.Commit();
            }
        }
    }

クラスとマッピング

public class Address : IEquatable<Address>, IEqualityComparer<Address>
    {
        protected Address() { }

        public Address(int number)
        {
            Number = number;
            Date = DateTime.Now;
        }

        public virtual int Number { get; protected set; }
        public virtual DateTime Date { get; protected set; }

        public override bool Equals(object obj)
        {
            return Number == ((Address)obj).Number;
        }

        public override int GetHashCode()
        {
            return Number.GetHashCode();
        }

        public bool Equals(Address other)
        {
            return Number == other.Number;
        }

        public bool Equals(Address x, Address y)
        {
            return x.Number == y.Number;
        }

        public int GetHashCode(Address obj)
        {
            return obj.GetHashCode();
        }
    }

    public class User
    {
        public virtual Guid Id { get; set; }
        public virtual string Name { get; set; }
        public virtual Address Address { get; set; }
    }

    public class UserMap : ClassMap<User>
    {
        public UserMap()
        {
            Table("test1");
            Id(x => x.Id).GeneratedBy.GuidNative();
            Map(x => x.Name);
            Component(x => x.Address, cm =>
            {
                cm.Map(x => x.Number);
                cm.Map(x => x.Date);
            });
        }
    }
4

1 に答える 1

1

Address をコンポーネントとしてマップしました。したがって、NHibernate に user.Address を Address インスタンスと比較するように依頼すると、すべての属性が比較されます。NHibernate は、Equals() メソッドでどのプロパティが使用されているかを判断するために、コンパイルされたコードを分析しません。

コードは正常に動作します。

アドレス全体を比較するのではなく、すべての属性を個別に比較するクエリを作成できます。または、設計を再考して、Address を真の値のオブジェクトにします。

于 2013-01-28T15:04:51.970 に答える