Какой правильный Fluent NHibernate ConventionBuilder для отличающихся имен на родительском?для систем с коричневыми полями тоже - PullRequest
0 голосов
/ 14 декабря 2010

Какой код нужно перейти сюда:

,ConventionBuilder.HasMany.Always(x => 
          x.Key.Column( /* what code need to go here? */ )) 

Помимо этого ...

public virtual Person Owner { get; set; }

... to (идеально подходит только для новых систем):

public virtual Person Person { get; set; }

Как я могу предотвратить создание NHibernate постороннего Person_id при создании DDL?

Обратите внимание, что Person_id был создан NH (или FNH?), Даже если уже есть owner_ref, и обратите внимание на две ссылки:

create table contact (contact_id int4 not null, 
                      number text, type text, owner_ref int4, 
                      Person_id int4, primary key (contact_id));
create table person (person_id int4 not null, person_name text not null, birthdate timestamp not null, primary key (person_id));
alter table contact 
      add constraint FK38B7242018FA494F 
      foreign key (owner_ref) references person;
alter table contact 
      add constraint FK38B724202B329A0D 
      foreign key (Person_id) references person;

Я попробовал это просто для того, чтобы убедиться, что возможно предотвратить посторонние ссылки

,ConventionBuilder.HasMany.Always(x => x.Key.Column("owner_ref"))   

Вот создание NHibernate DDL, когда я добавляю ConventionBuilder:

create table contact (contact_id int4 not null, number text, type text, 
                      owner_ref int4, primary key (contact_id));
create table person (person_id int4 not null, person_name text not null, birthdate timestamp not null, primary key (person_id));
alter table contact 
      add constraint FK38B7242018FA494F 
      foreign key (owner_ref) references person;

Примечание больше нет поля Person_id, и теперь есть только одна ссылка, и это правильно. Так что это предотвращает дублирование ссылок, возможно, но я все еще не знаю, как изменить имя коллекции KeyColumn (IList ) в разделе Person в ConventionBuilder

Другой способ - просто изменить KeyColumn в ClassMap напрямую, предотвращая дублирование ссылок в таблице контактов ...

HasMany(x => x.Contacts).Inverse().KeyColumn("owner_ref");

..., достигнут тот же SQL, что и выше, но лучше, если я смогу сделать его автоматическим на ConventionBuilder.

Как я могу сказать NHibernate от создания двух ссылок? Вот код сопоставления (обратите внимание: публичный виртуальный владелец Person {get; set;} . Это не Person Person {get; set;}

    public class Person
    {
        public virtual int PersonId { get; set; }

        public virtual string PersonName { get; set; }
        public virtual DateTime Birthdate { get; set; }     

        public virtual IList<Contact> Contacts { get; set; }
    }


    public class Contact
    {
        public virtual Person Owner { get; set; }

        public virtual int ContactId { get; set; }      
        public virtual string Number { get; set; }      
        public virtual string Type { get; set; }
    }





    public class PersonMap : ClassMap<Person>
    {
        public PersonMap()
        {       

            Id(x => x.PersonId);
            Map(x => x.PersonName).Not.Nullable();
            Map(x => x.Birthdate).Not.Nullable();                   
            HasMany(x => x.Contacts).Inverse(); 
        }
    }



    public class ContactMap : ClassMap<Contact>
    {
        public ContactMap()
        {                   
            References(x => x.Owner);
            Id(x => x.ContactId).GeneratedBy.Sequence("contact_contact_id_seq");
            Map(x => x.Number);
            Map(x => x.Type);                           
        }

    }

Какой правильный ConventionBuilder для этого шаблона проектирования (суффикс "_ ref" для поля дочерней таблицы, ссылающегося на родительскую таблицу). Это может произойти и в системах с коричневыми полями.

Ответы [ 2 ]

0 голосов
/ 16 декабря 2010

Я нашел (сформулировал) решение. Ключевым моментом является то, что мы должны установить соединительный ключ на обоих концах сущностей, то есть мы должны установить его на ConventionBuilder.HasMany и ConventionBuilder.References

ConventionBuilder.References - это решенная проблема. Это ConventionBuilder.HasMany.Always (x => ), который нам нужен, чтобы найти способ обхода ссылочного объекта (например, Владелец) из .ConventionBuilder.HasMany.Always код.

Мы должны нормализовать ссылки на основе сопоставлений «многие к одному» из ConventionBuilder.HasMany . К сожалению, свойство reference находится в защищенном доступе в ClassMap. Для этого мы должны расширить ClassMap и использовать этот расширенный класс в наших отображениях, чтобы мы могли пройти по ссылкам

Ниже приведено решение, которое я кодировал, проверьте код NormalizeReference здесь: http://www.ienablemuch.com/2010/12/brownfield-system-problem-on-fluent.html

0 голосов
/ 14 декабря 2010

Вы не можете сделать это автоматически. NH не может знать, что вы хотите использовать один и тот же внешний ключ для двух ссылок.


РЕДАКТИРОВАТЬ теоретическое решение:

Вам нужно как-то передать обратное свойство, потому что это недостающая часть.

ConventionBuilder
  .HasMany(x => x.Contacts)
  .KeyColumn(x => GetColumnNameOf((Contact c) => c.Owner));

Я не знаю, как реализовать это, чтобы получить этот синтаксис, но это в основном информация, которую вам нужно передать. Если вам повезет, вы можете получить тип (Contact) компилятором из свойства, которое вы отображаете.

В идеале вы получите это так:

ConventionBuilder
  .HasMany(x => x.Contacts)
  .InverseOf(c => c.Owner));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...