2013-08-27 4 views
0

У меня проблема с тем, что я просто не могу решить Google или искать в stackoverflow.EF HasOptional WithMany

У меня есть две таблицы JournalLines и Accounts, и я хочу ссылаться на учетную запись в журнале (я ненавижу экономию), но ссылка должна быть необязательной, и у учетной записи shoulnt есть свойство навигации в JournalLine (в идеале).

JournalLine:

public class JournalLine : Entity<int> 
{ 
    public int? Account_Id { get; set; } 
    public string Desc { get; set; } 
    public decimal Credit { get; set; } 
    public decimal Debit { get; set; } 
    public virtual Account Account { get; set; } 
} 

_account:

public class Account : Entity<int> 
{ 
    public string Accid { get; set; } 
    public string Desc { get; set; } 
    public int VatcodeId { get; set; } 
} 

И соответствующие отображения:

public class JournalLineMap : EntityTypeConfiguration<JournalLine> 
{ 
    public JournalLineMap() 
    { 
     HasKey(k => new { k.Id, k.Account_Id }); 
     Property(k => k.Id) 
      .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 

     ToTable("attJournalLines"); 
     HasEntitySetName("JournalLines"); 

     HasOptional(jl => jl.Account) 
      .WithMany() 
      .HasForeignKey(jl => jl.Account_Id); 
    } 
} 

public class AccountMap : EntityTypeConfiguration<Account> 
{ 
    public AccountMap() 
    { 
     ToTable("attAccounts"); 
     HasEntitySetName("Accounts"); 
    } 
} 

И.М. ошибка получение, как:

Один или несколько ошибок проверки были обнаружены в процессе генерации модели:

tSystem.Data.Entity.Edm.EdmAssociationType:: Кратность конфликты с ссылочной> ограничение в роли «JournalLine_Account_Target» в отношениях 'JournalLine_Account. > Поскольку все свойства в зависимой роли не имеют значения NULL, множественность главной роли должна быть «1».

Это смущает меня, и я надеюсь, что кто-то может пролить свет на проблему.

Update

Спасибо за ответы, это помогло мне на пути, и я получил отношение к работе, вынув ключ. Затем я получил wierd behavoir при назначении Account на JournalLine была создана повторяющаяся учетная запись. Как оказалось, это не такое странное поведение, поскольку im использует шаблон репозитория с инъекцией зависимости. Я не думал о том, что контекст не был тем же самым в обоих хранилищах, поэтому JournalLinesRepository не отслеживал учетную запись, которую я выбрал из своего собственного репозитория, и поэтому подумал, что разумно просто вставлять ее в качестве нового объекта. Это было решено путем ввода одного и того же контекста в хранилищах, поэтому отслеживание элементов работает так, как ожидалось. Еще раз спасибо за вашу помощь.

+0

Что такое 'Entity '? Возможно, я устарел на EF - это часть структуры, или это настраиваемый базовый класс, где - это свойство Id? – STW

+0

Правильно это просто пользовательский базовый класс, который определяет тип столбца Идентификатор. Немного избыточен в некоторых случаях, но полезен в других – Patrik

ответ

3

Ohlin's Answer правильно идентифицирует проблему - у вас не может быть составной первичный ключ с нулевым столбцом. Это вызывает некоторые вопросы о том, что вы пытаетесь моделировать.

Помимо первичного ключа, похоже, что ваша модель будет работать. На самом деле я думаю, что просто удаление HasKey(k => new { k.Id, k.Account_Id }); заставит все работать. Если вы это сделаете, то каждый JournalLine будет иметь свой собственный уникальный идентификатор и, возможно, связан с Account.

Это приведет к данным, такие как:

| AccountId | Desc   | 
| 123456789 | Some Account | 

| JournalId | AccountId | Description | Credit | Debit | 
|   1 |  null |  Some Tx | 100.00 | 0.0 | 
|   2 | 123456789 | Another Tx | 0.0 | 50.0 | 
|   3 | 123456789 |  MoreTx | 10.00 | 0.0 | 

С другой стороны, если причина, имеющим AccountId в вашем JournalLine ключа подразумевает, что каждый счет эффективно имеет свой собственный журнал (который звучит неопределенно знакомы с моими классами учетных записей), то ваше моделирование нуждается в некоторой настройке - или вам может понадобиться специальная «неклассифицированная» учетная запись, специально предназначенная для обработки транзакций, которые не применяются к конкретной учетной записи.

+0

Это почти работает так, как предполагалось, за исключением получения повторяющихся строк в таблице Account учетной записи, которую я добавляю в строку. – Patrik

+0

Чтобы создать новые JournalLines для существующей учетной записи, сначала необходимо получить учетную запись (что-то вроде 'context.Accounts.SingleOrDefault (acct => acct.Id == someAccountId)'). – STW

+0

То как им это делать. Но когда я сохраняю его, создается новая учетная запись в таблице, почему? – Patrik

3

При взгляде на код, который он «чувствует», как HasKey(k => new { k.Id, k.Account_Id }); может быть причиной проблемы, так как Account_Id является нулевым, и это обычно не принято в качестве ключа. Попробуйте удалить флаг nullable для Account_Id, чтобы посмотреть, что произойдет.

Edit: Ключи в EF

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

Вы уже добавляете ключ для Account_Id, когда указываете его как внешний ключ ниже, так зачем же вы его в качестве первичного ключа? Тем более, что вы разрешаете ему быть нулевым?

+0

Я считаю, что это правильно; было бы полезно лучше понять предполагаемые отношения. Если JournalLines иногда вводятся с помощью учетной записи, то это означает, что учетная запись является родителем. – STW

+0

. Я добавил немного к моему вопросу, но в основном я не понимаю, почему вы должны использовать Account_Id в качестве первичного ключа. И у вас нет ссылок от Account to JournalLines, поэтому они не могут быть связаны с учетной записью. – Ohlin

+0

Возможно, цель состоит в том, чтобы эффективно иметь журнал-за-счет, на котором выкладывается множество бухгалтерских книг (если я помню) – STW

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

  • Нет связанных вопросов^_^