0

我正在用 Fluent 学习 NHibernate。我正在尝试测试映射,但我的一项测试失败了。以下是实体、映射和测试类:

 public class Employee
{
    public virtual int Id { get; set; }
    public virtual string FirstName { get; set; }
    public virtual string MiddleName { get; set; }
    public virtual string LastName { get; set; }
    public virtual DateTime DateOfBirth { get; set; }     
    public virtual string Gender { get; set; }
    public virtual long Pesel { get; set; }      
    public virtual DateTime CreateDate { get; set; }        
    public virtual Address HomeAddress { get; set; }
    public virtual Address BusinessAddress { get; set; }
}
 public class Address
{
    public virtual int Id { get; set; }
    public virtual string Street { get; set; }
    public virtual string BuildingNumber { get; set; }
    public virtual string FlatNumber { get; set; }
    public virtual string Postocde { get; set; }
    public virtual string Town { get; set; }
    public virtual string Province { get; set; }
    public virtual string Country { get; set; }

    public virtual ICollection<Employee> EmployeeHomeAddresses { get; set; }
    public virtual ICollection<Employee> EmployeeBusinessAddresses { get; set; }
}

public class EmployeeMap : ClassMap<Employee>
{
    public EmployeeMap()
    {
        Table("Employee");

        Id(x => x.Id, "Id").GeneratedBy.Identity();

        Map(x => x.FirstName, "FirstName");
        Map(x => x.MiddleName, "MiddleName");
        Map(x => x.LastName, "LastName");
        Map(x => x.DateOfBirth, "DateOfBirth");
        Map(x => x.Gender, "Gender");
        Map(x => x.Pesel, "PESEL");
        Map(x => x.CreateDate, "CreateDate");
        References(x => x.HomeAddress, "HomeAddressId");
        References(x => x.BusinessAddress, "BusinnessAddressId");
    }    
}
public class AddressMap : ClassMap<Address>
    {
        public AddressMap()
        {
            Table("Address");

            Id(x => x.Id).GeneratedBy.Identity();

            Map(x => x.Street, "Street");
            Map(x => x.BuildingNumber, "BuildingNumber");
            Map(x => x.FlatNumber, "FlatNumber");
            Map(x => x.Town, "Town");
            Map(x => x.Postocde, "Postcode");
            Map(x => x.Province, "Province");
            Map(x => x.Country, "Country");

            HasMany(x => x.EmployeeHomeAddresses).KeyColumn("Id");
            HasMany(x => x.EmployeeBusinessAddresses).KeyColumn("Id");

        }
    }

[Test]
        public void CanCorrectlyMapEmplyee()
        {

            var homeAddress = new Address()
            {                     
                Street = "Test street 1",
                BuildingNumber = "20",
                FlatNumber = "2",
                Postocde = "11111",
                Town = "London",
                Province = "Some UK County",
                Country = "UK"                               
            };

            session.SaveOrUpdate(homeAddress);

            var businessAddress = new Address()
            {          
                Street = "Test street 2",
                BuildingNumber = "20",
                FlatNumber = "3",
                Postocde = "22222",
                Town = "Cracow",
                Province = "Malopolskie",
                Country = "Poland"
            };

            session.SaveOrUpdate(businessAddress);

            new PersistenceSpecification<Core.Model.Employee>(session)                
                .CheckProperty(x => x.FirstName, "Greg")
                .CheckProperty(x => x.LastName, "T")
                .CheckProperty(x => x.Gender, "M")
                .CheckProperty(x => x.DateOfBirth, DateTime.Now.TruncateToSeconds())
                .CheckProperty(x => x.Pesel, "12345678910")
                .CheckProperty(x => x.CreateDate, DateTime.Now.TruncateToSeconds())
                .CheckProperty(x => x.HomeAddress, homeAddress)
                .CheckProperty(x => x.BusinessAddress, businessAddress)
                .VerifyTheMappings();
        }

此测试失败。错误消息:对于属性“HomeAddress”,需要相同的元素,但得到了“SalesMaster.Core.Model.Address”类型的不同元素。我尝试使用 CheckReference 而不是 CheckProperty 作为外键,但它给了我同样的错误。使用我为 HomeAddress 传递的相同值进行地址测试。

在我添加外键之前,这个测试已经通过了。问题出在哪里?

4

1 回答 1

1

我认为问题出在您的 HasMany 映射中:

HasMany(x => x.EmployeeHomeAddresses).KeyColumn("Id");
HasMany(x => x.EmployeeBusinessAddresses).KeyColumn("Id");

我个人认为这有点误导,但是 KeyColumn 函数需要 Employee 表中的外键列的名称。所以它变成了这样:

HasMany(x => x.EmployeeHomeAddresses).KeyColumn("HomeAddressId");
HasMany(x => x.EmployeeBusinessAddresses).KeyColumn("BusinessAddressId");

请注意,映射工作实际上并不需要这些 HasMany 关系,因此除非您确实需要获取居住在特定地址的员工列表(这很奇怪),否则您可以完全删除它们并只保留您的 References 映射。

编辑: 最后似乎发生此错误是因为您需要在 Address 类中覆盖 Equals 和 GetHashCode 。当 Equals 没有被覆盖时,它只在两个对象完全相同的情况下返回 True,并且 NHibernate 会在您调用 SaveOrUpdate 时修改您的实体以将其转换为代理,这是默认行为。有关更多信息,请参阅此问题

public override bool Equals(object obj)
{
    if(ReferenceEquals(obj, this))
        return true;

    var addr = obj as Address;
    if(addr == null)
        return false;

    return addr.Country == this.Country && addr.State == this.State //and so on..
}
于 2013-09-18T22:08:15.230 回答