2013-09-14 3 views
5

ПОМОЩЬ! - Я получаю следующее сообщение об ошибке на моей навигационной модели СтатьяВид статьи:EF Code First: Нарушение ограничения множественности

A relationship multiplicity constraint violation occurred

Вот существующая схема базы данных:

database model

Вот мой код:

public class Article 
{ 
    public int ID { get; set; } 
    public virtual Stage Stage { get; set; } 
    public virtual ArticleType ArticleType { get; set; } // Causes the violation 
} 

public class ArticleType 
{ 
    public int ID { get; set; } 
    public string Title { get; set; } 
} 

public class Stage 
{ 
    public int ID { get; set; } 
    public string Title { get; set; } 
} 

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

// This works 
modelBuilder.Entity<Article> 
    .HasRequired(t => t.Stage) 
    .WithMany() // if turned .WithOptional() then will also cause the error. 
    .Map(m => m.MapKey("stage_id")); 

// This does not work 
modelBuilder.Entity<Article> 
    .HasRequired(t => t.ArticleType) 
    .WithMany() 
    .Map(m => m.MapKey("article_type_id")); 

Моя проблема заключается в том, что почему это, что СтатьяВид статьи вызывает ошибку но Stage не делает, даже когда оба-х декларации и отображение синтаксически то же самое?

EDIT 1

Я узнал об исключении, рассматривая объект статьи, наведя мышь (не уверен, что точный термин)

open image to new tabe

Подробно об

System.InvalidOperationException was unhandled by user code 
    HResult=-2146233079 
    Message=A relationship multiplicity constraint violation occurred: An EntityReference can have no more than one related object, but the query returned more than one related object. This is a non-recoverable error. 
    Source=System.Data.Entity 
    StackTrace: 
     at System.Data.Objects.DataClasses.EntityReference`1.Load(MergeOption mergeOption) 
     at System.Data.Objects.DataClasses.RelatedEnd.Load() 
     at System.Data.Objects.DataClasses.RelatedEnd.DeferredLoad() 
     at System.Data.Objects.Internal.LazyLoadBehavior.LoadProperty[TItem](TItem propertyValue, String relationshipName, String targetRoleName, Boolean mustBeNull, Object wrapperObject) 
     at System.Data.Objects.Internal.LazyLoadBehavior.<>c__DisplayClass7`2.<GetInterceptorDelegate>b__2(TProxy proxy, TItem item) 
     at System.Data.Entity.DynamicProxies.Package_A18FADC105CCF13C9CD346622D43BD35514E489CCC1E5B1E4A3C78806BDCA0F5.get_ArticleType() 
     at AuthorProofing.Service.ReminderService.DeliverDailyReminders() in C:\Users\default.Lenovo-PC\Documents\Visual Studio 2010\Projects\AuthorProofing\AuthorProofing.Service\ReminderService.cs:line 36 
     at AuthorProofing.Tests.ReminderServiceTest.DeliverDailyRemindersTest() in C:\Users\default.Lenovo-PC\Documents\Visual Studio 2010\Projects\AuthorProofing\AuthorProofing.Tests\ReminderServiceTest.cs:line 76 
    InnerException: 

EDIT 2

Я решил пойти с явными ассоциациями внешних ключей.

class ArticleMap : EntityTypeConfiguration<Article> 
{ 
    public ArticleMap() 
    { 
     // Primary Key 
     this.HasKey(t => t.ID); 
     this.Property(t => t.ID) 
      .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 

     // Strongly typed FK properties 
     this.Property(t => t.StageID).IsRequired(); 
     this.Property(t => t.ArticleTypeID).IsRequired(); 

     // Navigation Models 
     this.HasRequired(t => t.Stage); 
     this.HasRequired(t => t.ArticleType); 

     // Table & Column Mappings 
     this.ToTable("items"); 
     this.Property(t => t.ID).HasColumnName("item_id"); 
     this.Property(t => t.StageID).HasColumnName("stage_id"); 
     this.Property(t => t.ArticleTypeID).HasColumnName("article_type_id"); 
    } 
} 


protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Configurations.Add(new ArticleTypeMap()); 
    modelBuilder.Configurations.Add(new StageMap()); 
    modelBuilder.Configurations.Add(new ArticleMap()); 
} 

Все еще не работает.

Использование нового ключа проекционного подхода иностранный, я попытался переключить ключи article_type_id и stage_id.

this.Property(t => t.StageID).HasColumnName("article_type_id"); // <-- Switched 
this.Property(t => t.ArticleTypeID).HasColumnName("stage_id"); // <-- Switched 

Внезапно ошибка исчезла. В настоящее время сбиты с толку. Мне кажется, что модели ArticleType не нравится внешний ключ «article_type_id».

EDIT 3

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

class ArticleMap : EntityTypeConfiguration<Article> 
{ 
    public ArticleMap() 
    { 
     // Primary Key 
     this.HasKey(t => t.ID); 
     this.Property(t => t.ID) 
      .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 

     // Foreign Key Properties 
     this.Property(t => t.StageID) 
      .IsRequired(); 
     this.Property(t => t.JournalID) 
      .IsRequired(); 
     this.Property(t => t.ArticleTypeID) 
      .IsRequired(); 

     // Navigational Models 
     this.HasRequired(t => t.Stage); // This works 
     this.HasRequired(t => t.ArticleType) 
      .WithMany() 
      .HasForeignKey(t => t.ArticleTypeID); // Newly added 

     // Table & Column Mappings 
     this.ToTable("items"); 
     this.Property(t => t.ID).HasColumnName("item_id"); 
     this.Property(t => t.ArticleTypeID).HasColumnName("article_type_id"); 
     this.Property(t => t.StageID).HasColumnName("stage_id"); 
    } 
} 

class ArticleTypeMap : EntityTypeConfiguration<ArticleType> 
{ 
    public ArticleTypeMap() 
    { 
     // Primary Key 
     this.HasKey(t => t.ID); 

     // Properties 
     this.Property(t => t.ID) 
      .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); 

     this.Property(t => t.Title) 
      .HasMaxLength(100) 
      .IsRequired(); 

     // Table & Column Mappings 
     this.ToTable("article_types"); 
     this.Property(t => t.ID).HasColumnName("article_type_id"); // <-- Apparently, this is no longer mapped. 
     this.Property(t => t.Title).HasColumnName("title"); 
    } 
} 
+0

Я советую вам объяснять, добавьте внешние ключи в свой код. Поэтому добавьте свойство ArticleTypeID и StageID в класс «Article». Тем не менее, эти отношения должны быть подхвачены EntityFramework без какой-либо необходимости в настройке с использованием Fluent API или иным образом. – Dabblernl

+0

@Dabblernl Спасибо. Но я пытался избежать этого решения, поэтому я разместил этот вопрос, но я попробую это в качестве своего окончательного решения. – Yorro

+0

Почему вы пытаетесь избежать этого? Это сделает вашу жизнь намного проще, если вы сделаете ... – Dabblernl

ответ

8

Когда прибегая к помощи конкретной messagea ошибки, причиной этого делает ошибку конфигурирования один ко многим отношений, как один к одному отношения с помощью:

modelBuilder.Entity<Article> 
.HasRequired(t => t.ArticleType) 
.WithOptional() 
.HasForeignKey(...); 

Хотя это должно быть:

modelBuilder.Entity<Article> 
.HasRequired(t => t.ArticleType) 
.WithMany() 
.HasForeignKey(...); 

Вы уже указали это в своем собственном примере кода. В качестве кода вы указали для ArticleType, а Stage идентичен, что не имеет значения, что этот код является причиной проблемы. В другом месте вашего кода должно быть отношение один к одному, определенное между Article и ArticleType. Или каким-то образом у вас изначально было неправильное отношение, но исправленное свободное определение не подхвачено Entity Framework.

+0

Я решил явно объявить свойства внешнего ключа, ошибка все еще существует, поэтому проблема где-то происходит. См. Мой отредактированный пост. Благодаря! – Yorro

+0

После добавления «Свойства внешнего ключа» я добавил '.HasForeignKey (...)'. Внезапно «article_type_id» не удалось отобразить. См. Мой отредактированный пост. – Yorro

+0

Хорошо, я только что узнал, что где-то еще существует взаимно-однозначная связь между «ArticleType» и «Recipient» (какой-то другой класс, который даже не вызван, но вызвал ошибку) – Yorro

-4

Вы можете взять .edmx-файл из visual stdio и сопоставить базу данных с этим файлом, чтобы автоматически создавать сопоставление суффиксов отношения сущности в соответствии с схемой базы данных.

+0

Это не отвечает на вопрос вообще, для одного ГЭС с использованием кода сначала –

+1

Это для первого подхода кода с существующей базой данных. – Yorro

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