0

Я изучаю NHibernate с 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.

Этот тест прошел, прежде чем я добавил внешние ключи. Где проблема?

+0

Почему 'EmployeeHomeAddresses' и' EmployeeBusinessAddresses' имеют 'protected' модификатор к их набору? здесь нет наследования –

+0

Omribitan вы правы - я удалил эти модификаторы (только две строки скопированы и вставлены здесь, и я не заметил этого :)), но это не меняет результат теста. –

ответ

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 отношения на самом деле не нужны для вашего отображения на работу, так что, если вам действительно нужно, чтобы получить список сотрудников, проживающих по определенному адресу (который является странно), вы можете полностью удалить их и сохранить только сопоставления ссылок.

EDIT: И, наконец, кажется, что эта ошибка возникает из-за того, что вам необходимо переопределить Equals и GetHashCode в вашем классе Address. Когда Equals не переопределяется, он возвращает True только в том случае, если оба объекта абсолютно одинаковы, и NHibernate изменяет вашу сущность при вызове SaveOrUpdate, чтобы превратить ее в прокси-сервер, что является поведением по умолчанию. См. this question для получения дополнительной информации.

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.. 
} 
+0

Спасибо за этот отзыв. Как бизнес, так и домашние адреса вставляются в базу данных, поэтому кажется, что сопоставление в порядке, но тест все еще не выполняется. –

+0

Я обновил свой ответ с помощью другого решения (на что я надеюсь) – igelineau

+0

Это работает! Благодарю. –

Смежные вопросы