2017-02-01 46 views
1

我想創建我的第一個EF代碼第一個對象到數據庫中。不幸的是,當試圖將我的對象保存到數據庫中時,我得到以下異常:實體框架代碼與自引用對象的第一個錯誤

無法確定依賴操作的有效順序。 由於外鍵約束, 需求或商店生成的值,可能會存在依存關係。

這裏是我用來填充數據庫的代碼:

using (var context = new MySample.Context()) 
{ 
    context.Database.CreateIfNotExists(); 

    CloudFile f = new CloudFile(, "file1"); 

    CloudDirectory d = new CloudDirectory(CloudObject.CloudContentType.Customer, "directory1"); 
    d.Nodes.Add(d); 

    FileGroup g = new FileGroup(); 
    g.CloudObjects.Add(d); 

    context.FileGroups.Add(g); 
    context.SaveChanges(); 
} 

其實我想創建FileGroup類型的對象。該對象包含文件(CloudFile)或目錄(CloudDirectory)。目錄可以包含其他目錄或文件。

下面是類所提到的對象:

public class FileGroup { 

    public FileGroup() 
    { 
     CloudObjects = new HashSet<CloudObject>(); 
    } 

    public int FileGroupId { get; set; } 

    public string Name { get; set; } 

    public virtual ICollection<CloudObject> CloudObjects { get; set; } 
} 


public abstract class CloudObject { 

    public CloudObject(string name) 
    { 
     Name = name; 
    } 

    public int CloudObjectId { get; set; } 

    public string Name { get; set; } 

    public abstract bool hasChildren { get; } 

    public int? ParentId { get; set; } 

    public virtual Node Parent { get; set; } 

    public int? FileGroupId { get; set; } 

    public virtual FileGroup FileGroup { get; set; } 
} 

public class CloudDirectory : CloudObject { 

    public CloudDirectory(string name) :base(name) 
    { 
     Nodes = new HashSet<CloudObject>(); 
    } 

    public override bool hasChildren 
    { 
     get 
     { 
      return Nodes.Any(); 
     } 
    } 

    public virtual ICollection<CloudObject> Nodes { get; set; } 
} 

public class CloudFile : CloudObject { 

    public CloudFile(string name) : base(name) 
    { 
    } 

    public string ETag { get; set; } 

    public override bool hasChildren 
    { 
     get 
     { 
      return false; 
     } 
    } 
} 

任何想法,我需要在我的對象改變,使他們可以存儲成功地做到DB?

+0

什麼是'Node'這裏'公共虛擬節點父{獲得;組; }'? –

回答

1

在您的測試代碼一些變化(代碼註釋解釋它們):

using (var context = new MySample.Context()) 
{ 
    context.Database.CreateIfNotExists(); 

    CloudFile f = new CloudFile("file1"); 

    CloudDirectory d = new CloudDirectory("directory1"); 

    //This seems to be wrong: 
    //d.Nodes.Add(d); 
    d.Nodes.Add(f); //I guess you don't want d to be its own parent, but want it to be f's parent 

    FileGroup g = new FileGroup(); 
    g.CloudObjects.Add(d); 
    //Another way to do it: 
    //d.FileGroup = g; 

    //You also want f to be in the FileGroup, you have to add it explicitly 
    g.CloudObjects.Add(f); 
    //Another way to do it: 
    //f.FileGroup = g; 

    context.FileGroups.Add(g); 
    context.SaveChanges(); 
} 

由於實體之間的關係是有點太複雜了EF自動約定來對付他們,你應該添加顯式映射他們在DbContext

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    ... 
    modelBuilder.Entity<CloudObject>().HasOptional(x => x.Parent).WithMany(x => x.Nodes).HasForeignKey(x => x.ParentId); 
    modelBuilder.Entity<CloudObject>().HasOptional(x => x.FileGroup).WithMany(x => x.CloudObjects).HasForeignKey(x => x.FileGroupId); 
} 

注:我這裏假設FileGroup不強制指定CloudObject。如果是強制性的,您應該將方法HasOptional更改爲HasRequired

你也應該改變這種屬性的類型:

public abstract class CloudObject 
{ 
    ... 
    //public virtual Node Parent { get; set; } 
    public virtual CloudDirectory Parent { get; set; } 
    ... 
} 

您的遷移有幾分像這樣:

CreateTable(
    "dbo.CloudObjects", 
     c => new 
      { 
       CloudObjectId = c.Int(nullable: false, identity: true), 
       Name = c.String(), 
       ParentId = c.Int(), 
       FileGroupId = c.Int(), 
       ETag = c.String(), 
       Discriminator = c.String(nullable: false, maxLength: 128), 
      }) 
     .PrimaryKey(t => t.CloudObjectId) 
     .ForeignKey("dbo.FileGroups", t => t.FileGroupId) 
     .ForeignKey("dbo.CloudObjects", t => t.ParentId) 
     .Index(t => t.ParentId) 
     .Index(t => t.FileGroupId); 

CreateTable(
    "dbo.FileGroups", 
     c => new 
      { 
       FileGroupId = c.Int(nullable: false, identity: true), 
       Name = c.String(), 
      }) 
     .PrimaryKey(t => t.FileGroupId); 
相關問題