0

Я пытаюсь создатьКак ссылаться на класс с 2 cols CompositeId из класса с 2 cols CompositeId в FluentNhibernate?

public class BaseMap<T> : ClassMap<T> 

для моего приложения. Она должна поддерживать локализованные объекты, которые их первичный ключ должен быть как Id & Язык:

CompositeId() 
    .KeyProperty(x => x.Id) 
    .KeyProperty(x => ((ILocalizedEntity)x).Language); 

Другое дело, что я хочу один локализованный класс, чтобы иметь возможность ссылаться на другую локализованную класс.

Я сделал следующее (После того, как много исследований, это все у меня есть):

public new ManyToOnePart<TOther> References<TOther>(Expression<Func<T, TOther>> memberExpression) where TOther : BaseEntity 
    { 
     if (typeof(ILocalizedEntity).IsAssignableFrom(typeof(TOther))) 
     { 
      return base.References(memberExpression) 
       .Columns("CategoryId") 
       .Columns("Language"); 
     } 

     return base.References(memberExpression); 
    } 

Это дало мне IndexOutOfRange исключения при попытке вставить, причина в том, что свойство «Язык» отображался дважды, но был только один язык столбца в БД, так что я сделал это:

public new ManyToOnePart<TOther> References<TOther>(Expression<Func<T, TOther>> memberExpression) where TOther : BaseEntity 
    { 
     if (typeof(ILocalizedEntity).IsAssignableFrom(typeof(TOther))) 
     { 
      return base.References(memberExpression) 
       .Columns("CategoryId") 
       .Columns("Language") 
       .Not.Update() 
       .Not.Insert(); 
     } 

     return base.References(memberExpression); 
    } 

какая проблема решена IndexOutOfRange, но не выполнил то, что я хочу. потому что он всегда вставляет NULL в столбец «CategoryId», потому что я указал Not.Insert() и Not.Update(), так что это не так!

Теперь я в ситуации, когда хочу, чтобы он отображал «CategoryId», но не «Язык», потому что он уже отображен, так как он является частью ComposideId (первичный ключ).

Так что я дал попробовать это:

public new ManyToOnePart<TOther> References<TOther>(Expression<Func<T, TOther>> memberExpression) where TOther : BaseEntity 
    { 
     if (typeof(ILocalizedEntity).IsAssignableFrom(typeof(TOther))) 
     { 
      return base.References(memberExpression) 
       .Columns("CategoryId") 
       .Nullable() 
       .Columns("Language") 
       .Not.Update() 
       .Not.Insert(); 
     } 

     return base.References(memberExpression); 
    } 

желающих не будет вставлять или обновлять только «язык», а не «CategoryId» - но не повезло там.

Я также попытался сделать язык первым в ПК:

  CompositeId() 
       .KeyProperty(x => ((ILocalizedEntity)x).Language) 
       .KeyProperty(x => x.Id); 

И изменил ссылкиЧтобы:

  return base.References(memberExpression) 
       .Columns("Language") 
       .Not.Update() 
       .Not.Insert() 
       .Columns("CategoryId") 
       .Nullable(); 

Но все-таки "Not.Insert()" и «Не .Update() "влияет на оба" Язык "&" CategoryId ".

Я попытался картографирования "CategoryId" перед вызовом "Ссылки", как это:

  Map(memberExpression, "Language"); 
      return base.References(memberExpression) 
      ....... 

Но это не удалось.

У любого есть идея, как ссылаться на класс с 2 столбцами CompositeId из класса с 2 столбцами CompositeId, когда 1 из столбцов является общим для первичного ключа и внешнего ключа?

+0

избегать составных элементов как можно больше.следующее также избегает дублирования http://stackoverflow.com/a/5431842/671619 – Firo

+0

Тем не менее, если я хочу использовать их, почему это так сложно? Если вы думаете о том, что правильно архитектурно в программе и в db, составной идентификатор иногда является лучшим выбором ... не так ли? –

ответ

0

У меня была аналогичная проблема, когда часть составного элемента была ссылкой, и я не мог решить ее ни с помощью google, ни с моими силами, ни в течение 2 недель, а потому неприязни к ним.

Есть случаи, когда CompositeId имеет свое место, но в случае, если вы описываете, скорее всего, нет. Простой словарь и удобные свойства для получения значения для реального языка намного проще и позволяют дублировать все другие свойства, которые одинаковы для каждого языка.

+0

Действительно ли они всегда одинаковы для всех языков? Я не знаю .... То, что я пытался сделать, это применить логику локализации к каждому новому объекту ... Я просто хочу, чтобы он наследовал от интерфейса и позволял волшебству быть выполненным. Если бы это не было что небольшое ограничение по техническим причинам .. –

+1

некоторые недостатки: 1) вы всегда должны знать язык при запросе по id 2), вы всегда должны добавлять язык к каждому запросу 3) вам нужно управлять идентификатором самостоятельно (не можете использовать существующие idgenerators with compositeId) 4) Category.Color, Category.Type и т. д. будут дублироваться для каждого языка – Firo

+0

5) вы должны перезагрузить объект при переключении языка в своей программе; 6) реализовать откат, если локализованный объект отсутствует, означает, что вы необходимо снова запросить базу данных для объекта языка по умолчанию вместо того, чтобы иметь значение по умолчанию в словаре – Firo