IEntityChangeTracker の複数のインスタンスからエンティティオブジェクトを参照できない場合の対処法
EF を使用して、関係が確立しているテーブルに新しいレコードを追加する場合。
1つのエンティティオブジェクトを複数のIEntityChangeTrackerのインスタンスから参照することはできません。 または エンティティオブジェクトは、IEntityChangeTracker の複数のインスタンスから参照できません。
MVC + EF for demosの学習中に遭遇した例外メッセージ。Webでいくつか調べてもよくわからなかったので、しばらく放り投げていました。
まずはエラーコード。
public class CollegeInfo
{
private StudentManageContext stuCtx=new StudentManageContext();
public Models.CollegeInfoModel GetModel(Guid collegeId)
{
var model = stuCtx.CollegeInfoes.SingleOrDefault(s => s.CollegeId == collegeId);
return model;
}
public int Add(Models.CollegeInfoModel model)
{
stuCtx.CollegeInfoes.Add(model);
int count = stuCtx.SaveChanges();
return count;
}
public int Update(Models.CollegeInfoModel model)
{
Models.CollegeInfoModel oldModel = stuCtx.CollegeInfoes.Find(model.CollegeId);
oldModel = model;
stuCtx.Entry(oldModel).State = System.Data.EntityState.Modified;
return stuCtx.SaveChanges();
}
}
public class DepartmentInfo
{
private StudentManageContext stuCtx=new StudentManageContext();
public Models.DepartmentInfoModel GetModel(Guid departmentId)
{
var model = stuCtx.DepartmentInfoes.SingleOrDefault(s => s.DepartmentId == departmentId);
return model;
}
public int Add(Models.DepartmentInfoModel model)
{
stuCtx.DepartmentInfoes.Add(model);
int count = stuCtx.SaveChanges();
return count;
}
public int Update(Models.DepartmentInfoModel model)
{
Models.DepartmentInfoModel oldModel = stuCtx.DepartmentInfoes.Find(model.DepartmentId);
oldModel = model;
stuCtx.Entry(oldModel).State = System.Data.EntityState.Modified;
return stuCtx.SaveChanges();
}
}
使用表关系图:
この2つのテーブルは1対多の関係にあり、DepartmentInfoのcollegeInfoIdは外部キーである。
DepartmentInfoのコードを追加します。
static void Main(string[] args)
{
Database.SetInitializer<StudentManageContext>(new DropCreateDatabaseIfModelChanges<StudentManageContext>());
CollegeInfoModel collegex = 新しい BLL.CollegeInfo().GetModel()を使用します。 新しい Guid( "B956CA6F-DD7D-4436-9099-484366A5F0B7" ));
DepartmentInfoModel depart = new DepartmentInfoModel()
{
DepartmentId = Guid.NewGuid(),
DepartmentName = "depart" + DateTime.Now.ToString(),
CollegeInfoObj = collegex
};
new BLL.DepartmentInfo().Add(depart);
}
この時点では、次のように表示されます。 1 つのエンティティオブジェクトを IEntityChangeTracker の複数のインスタンスで参照することはできません。 または エンティティオブジェクトは、IEntityChangeTracker の複数のインスタンスから参照できません。 の例外です。
その理由は CollegeInfoModel collegex = 新しい BLL.CollegeInfo().GetModel()を使用します。 新しい Guid( "B956CA6F-DD7D-4436-9099-484366A5F0B7" ));および 新しい BLL.DepartmentInfo().Add(depart)。 この2行のコードは、2つの異なるStudentManageContextオブジェクトを使用することで発生します。エラーコードを詳しく見てみると、どちらのクラスにも プライベート StudentManageContext stuCtx= 新しい StudentManageContext();を使用します。 <スパン もうお分かりでしょうか。要するに、やりたい操作はすべて同じDbContext上で行わなければならないのです。 注:StudentManageContextはDbContextから派生したものです。
解決策1
static void Main(string[] args)
{
Database.SetInitializer<StudentManageContext>(new DropCreateDatabaseIfModelChanges<StudentManageContext>());
CollegeInfoModel collegex = new BLL.CollegeInfo().GetModel(new Guid("B956CA6F-DD7D-4436-9099-484366A5F0B7"));
DepartmentInfoModel depart = new DepartmentInfoModel()
{
DepartmentId = Guid.NewGuid(),
DepartmentName = "depart" + DateTime.Now.ToString(),
};
//new BLL.DepartmentInfo().Add(depart); 将这句代码改成下面两句
collegex.Departments.Add(depart);
new BLL.CollegeInfo().Update(collegex);
}
原因就是:Update时与GetModel用得时同一个DBContext。
解决方案二:
public class CollegeInfo:BaseModel
{
public Models.CollegeInfoModel GetModel(Guid collegeId)
{
var model = stuCtx.CollegeInfoes.SingleOrDefault(s => s.CollegeId == collegeId);
return model;
}
public int Add(Models.CollegeInfoModel model)
{
stuCtx.CollegeInfoes.Add(model);
int count = stuCtx.SaveChanges();
return count;
}
public int Update(Models.CollegeInfoModel model)
{
Models.CollegeInfoModel oldModel = stuCtx.CollegeInfoes.Find(model.CollegeId);
oldModel = model;
stuCtx.Entry(oldModel).State = System.Data.EntityState.Modified;
return stuCtx.SaveChanges();
}
}
public class DepartmentInfo:BaseModel
{
public Models.DepartmentInfoModel GetModel(Guid departmentId)
{
var model = stuCtx.DepartmentInfoes.SingleOrDefault(s => s.DepartmentId == departmentId);
return model;
}
public int Add(Models.DepartmentInfoModel model)
{
stuCtx.DepartmentInfoes.Add(model);
int count = stuCtx.SaveChanges();
return count;
}
public int Update(Models.DepartmentInfoModel model)
{
Models.DepartmentInfoModel oldModel = stuCtx.DepartmentInfoes.Find(model.DepartmentId);
oldModel = model;
stuCtx.Entry(oldModel).State = System.Data.EntityState.Modified;
return stuCtx.SaveChanges();
}
}
public abstract class BaseModel
{
protected StudentManageContext stuCtx = null;
public BaseModel()
{
stuCtx = DataCache.GetCache("StudentManageContext") as StudentManageContext;
if (stuCtx == null)
{
stuCtx = new StudentManageContext();
DataCache.SetCache("StudentManageContext", stuCtx);
}
}
}
これにより、CollegeInfoとDepartmentInfoが同じDBContextを共有することができるようになる。
取得元:https://www.cnblogs.com/guolihao/p/3213723.html
関連
-
mysql reports Access denied; you need (at least one of) SUPER privilege(s) for this operation
-
2021MySql-8.0.26インストール詳細チュートリアル(ベビーシッターレベル)
-
unixODBC:データソース名が見つからない、デフォルトドライバが指定されていないに関する質問
-
解決方法 テーブルの定義が正しくありません。自動列は1つだけで、キーとして定義する必要があります。
-
解決策: テーブルの定義が正しくありません。
-
は、GROUP BY句に含まれるか、集約関数で使用される必要があります。
-
ORA-30926: ソース・テーブルの安定した行のセットを取得できませんか?
-
MySqlエラー解析'where節'の未知の列'xxx'
-
MySQL上級SQLステートメント
-
mysql: この操作には (少なくとも 1 つの) RELOAD 権限が必要です。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
(NTDLL.DLL): 0xC0000005: アクセス違反 - 解決
-
Hibernateでhibernate.propertiesが見つからない問題とデータベース方言の更新の問題
-
MySQLデータベースのクエリ機能を使用する際に、グループ関数の使用が無効である問題の解決方法
-
EF Exception Inquiry (エンティティオブジェクトは、IEntityChangeTrackerの複数のインスタンスから参照できません。)...
-
SQL SERVER データベース SELECT INTO および INSERT INTO の使用法(テンポラリテーブルへのデータ挿入を含む)
-
ORA-06550 "の解決策。1 行目、7 列目"
-
ORA-65096 無効な共通ユーザー名またはロール名
-
DB2 SQL エラーの解決法。sqlcode=-420, sqlstate=22018
-
Linuxでmysql-5.7.30をインストールするための詳細な手順
-
AttributeError: 'function' オブジェクトには 'cursor' という属性がありません。