1

我想按组件查询 NHibernate Linq。该组件包含一个 Date 属性,该属性未包含覆盖 Equals中。我只想在要求相等时跳过 Date 属性。目前在Address 类的 ctor 中设置了 Date 属性,因此查询将返回0 行。我知道这打破了值对象的概念,但我只想知道为什么下面的代码不能正常工作。

THE QUERY 如您所见,日期属性在查询中

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

您已将地址映射为组件。因此,当您要求 NHibernate 将 user.Address 与某个 Address 实例进行比较时,它会比较每个属性。NHibernate 不会分析编译后的代码来确定 Equals() 方法中使用了哪些属性。

代码工作正常。

您可以编写查询来分别比较每个属性,而不是比较整个地址。或者尝试重新思考设计,使 Address 成为真正的价值对象。

于 2013-01-28T15:04:51.970 回答