1

進口記錄時,我會用導致以防萬一故障代碼有一些超級明顯,我很想念開始:EF核心:我結束了重複的數據庫json.net

foreach(JToken OrgToken in json["Orgs"]) { 
    Debug.WriteLine("Org " + OrgToken["Name"]); 
    Org o = OrgToken.ToObject <Org>(); 
    _cont.Orgs.Add(o); 
    _influxClient.CreateDatabaseAsync(o.MetricDatabaseName); 

    foreach(JToken PortfolioToken in OrgToken["Portfolios"]) { 
     Debug.WriteLine("Portfolio " + PortfolioToken["Name"]); 
     Portfolio p = PortfolioToken.ToObject <Portfolio>(); 
     p.OrganizationId = o.Id; 
     _cont.Portfolios.Add(p); 

     foreach(JObject ProjectToken in PortfolioToken["Projects"]) { 
      Debug.WriteLine("Project " + ProjectToken["Name"]); 
      Project prj = ProjectToken.ToObject <Project>(); 
      prj.PortfolioId = p.Id; 
      _cont.Projects.Add(prj); 
      _cont.SaveChanges(); 
     } 
    } 
} 
_cont.SaveChanges(); 

這代碼將從JSON文件加載相關對象的層次結構(Org-> Portfolio->項目):

{ 
    "Orgs": [ 
    { 
     "Name": "StrongSoft", 
     "Users": [ 
     { 
      "email": "[email protected]", 
      "password": "password", 
      "IsOrgAdmin": true 
     }, 
     { 
      "email": "[email protected]", 
      "password": "password", 
      "IsOrgAdmin": false 
     } 
     ], 
     "Portfolios": [ 
     { 
      "Name": "Financial", 
      "Projects": [ 
      { "Name": "Derivatives Trading" }, 
      { "Name": "Fixed Income" }, 
      { "Name": "Fix Market Connector" } 
      ] 
     }, 
     { 
      "Name": "Machinery", 
      "Projects": [ 
      { "Name": "Hard Metal Stuff" }, 
      { "Name": "Health Management Framework" }, 
      { "Name": "Look and Poock" } 
      ] 
     }, 
     { 
      "Name": "Lab", 
      "Projects": [ 
      { "Name": "[email protected]#$%^&*()_+++++++++w+" }, 
      { "Name": "Какое-то странное имя, это капец" }, 
      { "Name": "" } 
      ] 
     } 
     ] 
    }, 
    { 
     "Name": "Clevereer", 
     "Users": [ 
     { 
      "email": "[email protected]", 
      "password": "password", 
      "IsOrgAdmin": true 
     }, 
     { 
      "email": "[email protected]", 
      "password": "password", 
      "IsOrgAdmin": false 
     } 
     ], 
     "Portfolios": [ 
     { 
      "Name": "Prospects", 
      "Projects": [ 
      { "Name": "AI Assisted Surveillance" }, 
      { "Name": "Metrics Keeper" } 
      ] 
     } 
     ] 
    } 
    ] 
} 

的問題是,當這種運行,我最終具有用於每個Portfolio對象和2次重複Project中的每一個都有3個副本。 Org沒有重複。

我已經確定了循環使「停止」和對象的適當數量的唯一嘗試創建一次(因此Debug.WriteLine()):

Org StrongSoft 
Portfolio Financial 
Project Derivatives Trading 
Project Fixed Income 
Project Fix Market Connector 
Portfolio Machinery 
Project Hard Metal Stuff 
Project Health Management Framework 
Project Look and Poock 
Portfolio Lab 
Project [email protected]#$%^&*()_+++++++++w+ 
Project Какое-то странное имя, это капец 
Project 
Org Clevereer 
Portfolio Prospects 
Project AI Assisted Surveillance 
Project Metrics Keeper 

我試圖SaveChanges()Attach()程序

我試着改變EntityState增加的對象,以便EF不會假設它們被改變並試圖重新創建它們

沒有什麼可以爲我工作。

我懷疑問題的根源在於關係,但我只提到/設置爲Id字段(這似乎不會觸發相關模型的Navigation Property的人口 - 爲什麼會造成問題?)我不知道我是不是正確保存對象,或者是不正確的實體設計。當我通過控制器保存實體(包括定義它們的關係)時,不會發生重複。

的實體和它們的關係是相當簡單:

public class Org : BaseEntity, IEntityBase 
    { 
     public string Name { get; set; } 
     public List<Portfolio> Portfolios { get; set; } 

    } 

public class Portfolio : BaseEntity, IEntityBase 
    { 
     public string Name { get; set; } 

     public int OrganizationId { get; set; } 
     [ForeignKey("OrganizationId")] 
     public virtual Org Organization { get; set; } 

     public bool IsPrivate { get; set; } 
     public List<Project> Projects {get;set;} 
    } 
} 

public class Project : BaseEntity, IEntityBase 
    { 
     public string Name { get; set; } 
     public int PortfolioId { get; set; } 
     [ForeignKey("PortfolioId")] 
     public Portfolio Portfolio { get; set; } 
    } 

更新:我嘗試了各種東西,此問題得到解決,其中包括:

調用_cont.SaveChanges()每一個對象被添加到dbSet時間:

Org o = OrgToken.ToObject<Org>(); 
_cont.Orgs.Add(o); 
_cont.SaveChanges(); 

從數據庫中檢索保存的對象以創建關係:

Portfolio p = PortfolioToken.ToObject<Portfolio>(); 
p.OrganizationId = _cont.Orgs.Find(o.Id).Id; 
_cont.Portfolios.Add(p); 
_cont.SaveChanges(); 

Portfolio p = PortfolioToken.ToObject<Portfolio>(); 
p.Organization = _cont.Orgs.Find(o.Id); 
_cont.Portfolios.Add(p); 
_cont.SaveChanges(); 

Portfolio p = PortfolioToken.ToObject<Portfolio>(); 
p.Organization = _cont.Find<Org>(p.id); 
_cont.Portfolios.Add(p); 
_cont.SaveChanges(); 

我的上下文是沒有任何幻想,我不認爲這有什麼,可能會影響它:

public class CoreContext : DbContext 
{ 
    public DbSet<Org> Orgs { get; set; } 
    public DbSet<Portfolio> Portfolios { get; set; } 
    public DbSet<Project> Projects { get; set; } 
    public DbSet<Metric> Metrics { get; set; } 
    public DbSet<OrgAccess> OrgAccess { get; set; } 

    public CoreContext(DbContextOptions<CoreContext> options) : base(options) { } 
    protected override void OnModelCreating(ModelBuilder modelBuilder) 
     { 
      foreach (var relationship in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys())) 
      { 
       relationship.DeleteBehavior = DeleteBehavior.Restrict; 
      } 

      modelBuilder.Entity<Org>().ToTable("Org").HasIndex(c=>c.Name).IsUnique(); 
      modelBuilder.Entity<Portfolio>().ToTable("Portfolio").HasOne(a => a.Organization); 
      modelBuilder.Entity<Project>().ToTable("Project"); 
     } 
    } 
} 
+0

其國圖的管理,因爲它不知道如何處理組織(S)的插入,沒有[機構的實際使用SaveChanges()'將它們推到數據庫中,直到它們被跳到數據包中,然後才跳到第一個循環中,如果有Id,我會感到驚訝。與我相信的項目組合相同。 – mvermef

+0

我試圖在添加對象時立即保存更改 - 無法治癒 – abolotnov

+0

爲什麼實體框架將現有對象重新插入到我的數據庫中? http://msdn.microsoft.com/en-us/magazine/dn166926.aspx – Colin

回答

2

該問題與Ent無關ityFramework或上下文或數據庫。問題在於Newtonsoft JSON映射器如何工作。並不是說這是一個問題,但是在轉換部分JSON文件.ToObject<T>()時,如果它們的名稱轉換符合對象類之間的關係,它將創建底層對象(我假設)。它對PortfolioProject這樣做,但是對於Users收集沒有這樣做,因爲模型之間沒有關係。

我希望它沒有這麼含蓄,但它就是這樣。我分享這個以防萬一有人碰到這個麻煩。

生成的代碼需要看起來像這樣:

public void CreateOrgStructure(string path = "/Test/TestData.json"){ 
     string DataFilePath = AppContext.BaseDirectory + path; 
     JObject json = JObject.Parse(File.ReadAllText(DataFilePath)); 
     foreach (JToken OrgToken in json["Orgs"]) 
      { 
       Debug.WriteLine("Org "+OrgToken["Name"]); 
       Org o = OrgToken.ToObject<Org>(); 
       _cont.Orgs.Add(o); 
       _cont.SaveChanges(); 
     } 
}