將資料存盤到資料庫的最佳方法是什么,同時將多個類一起插入資料庫。我有大約 10 個類,我想將所有資料一起保存到資料庫中。
發布一些有關系的類:
Public class ClassMain
{
public int ClassMainId { get; set; }
}
Public class ClassA
{
public int ClassAId { get; set; }
public int ClassMainId { get; set; }
public string ClassAName { get; set; }
}
Public class ClassB
{
public int ClassBId { get; set; }
public int ClassMainId { get; set; }
public string ClassBName { get; set; }
}
像上面一樣,我還有一些其他表與關系
我想一次性插入這些資料,如果有任何失敗,我想回滾資料,在物體框架或存盤程序方法中我們有沒有辦法做到這一點。
我正在通過這種方法來實作
https://dotnettutorials.net/lesson/unit-of-work-csharp-mvc/
還有其他方法嗎?
uj5u.com熱心網友回復:
如果使用相同的 DbContext 和單個SaveChanges()呼叫插入它們,它們將在同一個事務中提交。
如果物體與 FK 相互關聯,那么您希望 DB 管理 PK 并自動決議 FK 的最佳解決方案是設定導航屬性并將從屬物體添加到頂級物體,然后將頂級的添加到它們各自的 DBSet 并呼叫 SaveChanges。
在你的情況下,你會想要這樣的:
public class ClassMain
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ClassMainId { get; set; }
[InverseProperty("ClassMain")]
public virtual ICollection<ClassA> ClassAs { get; set;} = new List<ClassA>();
[InverseProperty("ClassMain")]
public virtual ICollection<ClassB> ClassBs { get; set;} = new List<ClassB>();
}
public class ClassA
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ClassAId { get; set; }
public int ClassMainId { get; set; }
[ForeignKey("ClassMainId")]
public virtual ClassMain ClassMain{ get; set; }
public string ClassAName { get; set; }
}
Public class ClassB
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ClassBId { get; set; }
public int ClassMainId { get; set; }
[ForeignKey("ClassMainId")]
public virtual ClassMain ClassMain{ get; set; }
public string ClassBName { get; set; }
}
對于 EF Core 5,ClassA 和 B 中的 FK ClassMainId 是可選的。EF Core 可以簡單地將陰影屬性用于映射,而不是將它們作為屬性公開。(受到推崇的)
現在,當您創建 ClassMain 和關聯的 A 和 B 時,您只需實體化新實體,填充各種欄位,并將頂級物體添加到 DbSet。
using(var context = new AppDbContext())
{
var newMain = new ClassMain
{
// ... set main properties, but don't worry about PK
ClassA = new ClassA { ClassAName = someAName },
ClassB = new ClassB { ClassBName = someBName }
};
context.ClassMains.Add(newMain);
context.SaveChanges();
}
您也可以在沒有身份 PK 的情況下執行此操作,您可以在代碼中設定 PK/FK,但您有責任確保它們是唯一的。通過設定導航屬性,EF 將在保存所有內容時負責關聯 FK。他們會一起保存或根本不保存。
編輯:如果您不希望 ClassMain 包含 ClassA 和 ClassB 實體的集合,則可以洗掉這些集合和 InverseProperty 屬性。填充實體看起來更像是:
using(var context = new AppDbContext())
{
var newMain = new ClassMain();
var classA = new ClassA { ClassAName = someAName, ClassMain = newMain };
var classB = new ClassB { ClassBName = someBName, ClassMain = newMain };
context.ClassAs.Add(classA);
context.ClassBs.Add(classB);
context.SaveChanges();
}
在這種情況下,ClassMain 實體將與 ClassA 和 B 一起保存。
uj5u.com熱心網友回復:
如果你有表之間的關系,@Steve Py 說的解決方案是最好的。但如果物體之間沒有任何關系,則可以使用顯式事務。
using var context = new AppDbContext();
using var transaction = context.Database.BeginTransaction();
var newMain = new ClassMain();
context.ClassMains.Add(newMain);
context.SaveChanges();
var newClassA = new ClassA
{
ClassMainId = newMain.ClassMainId
};
context.ClassAs.Add(newClassA);
var newClassB = new ClassB
{
ClassMainId = newMain.ClassMainId
};
context.ClassBs.Add(newClassB);
context.SaveChanges();
transaction.Commit();
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/313342.html
標籤:asp.net-mvc 实体框架
