2013-04-20 63 views
1

我试图链接列表的子和一个视频对象的主要子级与删除级联。EF多个属性引用相同的类型

我发现一些页面解释了如何为同一类型的2个单个对象执行此操作。但不适用于列表和单个对象。
How can I set up two navigation properties of the same type in Entity Framework

这里是我的代码:

using System.Collections.Generic; 
using System.Data.Entity; 
using System.Data.Entity.Infrastructure; 

namespace DataAccess 
{ 
    public class SimpleVideo 
    { 
     public string Name { get; set; } 
     public int SimpleVideoId { get; set; } 
     public virtual List<Sub> Subs { get; set; } 
     public Sub MainSub { get; set; } 
    } 

    public class Sub 
    { 
     public int SubId { get; set; } 
     public string Language { get; set; } 
    } 

    class VideoContext : DbContext 
    { 
     public DbSet<SimpleVideo> SimpleVideos { get; set; } 
     public DbSet<Sub> Subs { get; set; } 

     protected override void OnModelCreating(DbModelBuilder modelBuilder) 
     { 
      Database.SetInitializer(new DropCreateDatabaseAlways<VideoContext>()); 

      modelBuilder.Entity<SimpleVideo>().HasMany(v => v.Subs).WithOptional().WillCascadeOnDelete(true); 
      modelBuilder.Entity<SimpleVideo>().HasOptional(v => v.MainSub).WithRequired().WillCascadeOnDelete(true); 

      base.OnModelCreating(modelBuilder); 
     } 
    } 
} 

我不能得到这个工作。 当我只启用了一个modelBuilder行,它的工作原理。 我如何让他们两人同时工作?

System.Data.SqlServerCe.SqlCeException was unhandled 
    HResult=-2147467259 
    Message=The referential relationship will result in a cyclical reference that is not allowed. [ Constraint name = FK_dbo.Subs_dbo.SimpleVideos_SubId ] 
    Source=SQL Server Compact ADO.NET Data Provider 
    ErrorCode=-2147467259 
    NativeError=25083 
    StackTrace: 
     at System.Data.SqlServerCe.SqlCeCommand.ProcessResults(Int32 hr) 
     at System.Data.SqlServerCe.SqlCeCommand.ExecuteCommandText(IntPtr& pCursor, Boolean& isBaseTableCursor) 
     at System.Data.SqlServerCe.SqlCeCommand.ExecuteCommand(CommandBehavior behavior, String method, ResultSetOptions options) 
     at System.Data.SqlServerCe.SqlCeCommand.ExecuteNonQuery() 
     at System.Data.Entity.Migrations.DbMigrator.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement) 
     at System.Data.Entity.Migrations.Infrastructure.MigratorBase.ExecuteSql(DbTransaction transaction, MigrationStatement migrationStatement) 
     at System.Data.Entity.Migrations.DbMigrator.ExecuteStatements(IEnumerable`1 migrationStatements) 
     at System.Data.Entity.Migrations.Infrastructure.MigratorBase.ExecuteStatements(IEnumerable`1 migrationStatements) 
     at System.Data.Entity.Migrations.DbMigrator.ExecuteOperations(String migrationId, XDocument targetModel, IEnumerable`1 operations, Boolean downgrading, Boolean auto) 
     at System.Data.Entity.Migrations.DbMigrator.AutoMigrate(String migrationId, XDocument sourceModel, XDocument targetModel, Boolean downgrading) 
     at System.Data.Entity.Migrations.Infrastructure.MigratorBase.AutoMigrate(String migrationId, XDocument sourceModel, XDocument targetModel, Boolean downgrading) 
     at System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId) 
     at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Upgrade(IEnumerable`1 pendingMigrations, String targetMigrationId, String lastMigrationId) 
     at System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration) 
     at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update() 
     at System.Data.Entity.Internal.DatabaseCreator.CreateDatabase(InternalContext internalContext, Func`3 createMigrator, ObjectContext objectContext) 
     at System.Data.Entity.Internal.InternalContext.CreateDatabase(ObjectContext objectContext) 
     at System.Data.Entity.Database.Create(Boolean skipExistsCheck) 
     at System.Data.Entity.Database.Create() 
     at System.Data.Entity.DropCreateDatabaseAlways`1.InitializeDatabase(TContext context) 
     at System.Data.Entity.Database.<>c__DisplayClass2`1.<SetInitializerInternal>b__0(DbContext c) 
     at System.Data.Entity.Internal.InternalContext.<>c__DisplayClass8.<PerformDatabaseInitialization>b__6() 
     at System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action) 
     at System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization() 
     at System.Data.Entity.Internal.LazyInternalContext.<InitializeDatabase>b__4(InternalContext c) 
     at System.Data.Entity.Internal.RetryAction`1.PerformAction(TInput input) 
     at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(Action`1 action) 
     at System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase() 
     at System.Data.Entity.Internal.InternalContext.Initialize() 
     at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) 
     at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize() 
     at System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext() 
     at System.Data.Entity.Internal.Linq.InternalSet`1.ActOnSet(Action action, EntityState newState, Object entity, String methodName) 
     at System.Data.Entity.Internal.Linq.InternalSet`1.Add(Object entity) 
     at System.Data.Entity.DbSet`1.Add(TEntity entity) 
     at DataAccess.Program.Main() in c:\MMProject\TestProjects\DataAccess\Program.cs:line 63 
     at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
     at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
     at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
     at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
     at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
     at System.Threading.ThreadHelper.ThreadStart() 
    InnerException: 
+0

模型生成器行是什么? – 2013-04-20 20:43:23

回答

0

看看这个帖子我的完全相同的结构处理(据我可以告诉)...
Entity Framework One-to-Many with Default

我没有测试这一点 - 所以才替换名称 - 这应该工作,我认为...

modelBuilder.Entity<SimpleVideo>() 
    .HasOptional(x => x.MainSub) 
    .WithOptionalPrincipal() // x => x.DefaultForEntity) 
    .WillCascadeOnDelete(true); 

你不需要另一个关系 - 级联是默认情况下。

+1

首先,感谢您的回复。这里使用的类只是为了测试场景。这两个属性是完全独立的,MainSub属性中的对象不存在于列表Subs中。所以MainSub不是“默认”。 – 2013-04-22 07:32:18

+0

它的'语义'无关紧要 - 你的数据看起来就像那样。 – NSGaga 2013-04-22 15:20:20

相关问题