[英]Adding multiple same record to DB
我試圖多次向數據庫添加同一對象(只是更改屬性),但是問題是將第一條記錄添加到數據庫后,該記錄獲得了ID,而其他記錄無法添加。
我的模特:
class MyClass{
int id {set;get;}
string name {set;get;}
string color {set;get;}
//and other properities.
}
我的控制器:
public ActionResult Test(MyClass obj,int Counter){
for(int i=0;i<Counter;i++){
MyClass NewObject=obj;
NewObject.name=obj.name+" "+i.ToString();
Db.MyClass.Add(NewObject);
Db.SaveChanges();
}
}
例如,如果我的對象是:name =“ theName”; Color =“ Red”; 計數器是3; 所以我的預期輸出是:
- 第一條記錄:name =“ theName 0”; Color =“ Red”;
- 第二條記錄:name =“ theName 1”; Color =“ Red”;
- 第三條記錄:name =“ theName 2”; Color =“ Red”;
但是會發生什么,就是在添加第一條記錄后,NewObject將具有一個ID,但是obj的問題也具有ID,盡管我沒有將其添加到數據庫中! 因此,第二條記錄將返回錯誤(“已成功提交對數據庫的更改,但是在更新對象上下文時發生了錯誤。”)
您永遠不應使用同一對象來表示數據庫中的多個對象。 在幕后,EF保留對它知道的數據對象的引用,這些引用很重要。
如果要添加很多相似的對象,則有多個選項。 其中兩個是:
使用一種方法來使新對象不完整
您可以使用通用方法初始化對象的多個實例,而僅添加不同的屬性值(如果您使用的是C#7,則您的方法也可以是本地函數):
MyClass CreateInstance() {
return new MyClass {
Name = "theName";
Color = "Red";
}
}
public ActionResult Test(MyClass obj, int Counter){
for(int i = 0; i < Counter; i++){
MyClass newObject = CreateInstance();
newObject.Name = newObject.Name + " " + i.ToString();
Db.MyClass.Add(newObject);
Db.SaveChanges();
}
}
使對象可克隆
您可以使對象成為可Clone
(可以實現ICloneable
接口,但是這里不需要這樣做,它的Clone
方法返回一個object
):
class MyClass{
public int Id { set; get; }
public string Name { set; get; }
public string Color { set; get; }
public MyClass Clone() {
MyClass clone = (MyClass)MemberwiseClone();
clone.Id = 0;
return clone;
}
}
public ActionResult Test(MyClass obj, int Counter){
for(int i = 0; i < Counter; i++){
MyClass newObject = obj.Clone();
newObject.Name = obj.Name + " " + i.ToString();
Db.MyClass.Add(newObject);
Db.SaveChanges();
}
}
您應該使用哪個選項,完全取決於您的特定用例。
將一個復雜對象分配給另一個復雜對象會導致指向源對象的指針或引用,因此,所做的任何修改都將反映到由兩個變量引用的一個實例。 您可以通過檢查對象的哈希碼在.net中看到此內容。 要進行深度克隆或進行復制,您需要使用new MyObject()
在內存中構造一個新對象,然后將簡單類型值復制過來。 您將需要實例化並復制所有本身是復雜對象的子屬性。
public ActionResult Test(MyClass obj,int Counter){
for(int i=0;i<Counter;i++){
MyClass NewObject=new MyClass();
NewObject.name=obj.name+" "+i.ToString();
NewObject.color = obj.color;
Db.MyClass.Add(NewObject);
Db.SaveChanges();
}
}
一種方法是在每次循環迭代中使用類似的方法構造一個新對象(我已更改了變量名稱以匹配更常見的做法):
public ActionResult Test(MyClass baseObj,int Counter){
for(int i=0;i<Counter;i++) {
MyClass newObject = new MyClass()
{
Name = baseObj.Name,
Color = baseObj.Color
};
Db.MyClass.Add(NewObject);
Db.SaveChanges();
}
}
但是,在理想情況下,這將在業務邏輯層中進行處理以維護關注點分離 。 使用這種方法,所有對象的構造都將在調用添加到數據庫的任何方法之前進行。 然后,您可以傳入List<MyObject>
並使用Db.MyClass.AddRange(listOfObjectsPassed)
類的東西在相應的數據層方法中添加列表。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.