City와 관련된 직원 세부 정보를 저장하려고합니다. 그러나 연락처를 저장하려고 할 때마다 “ADO.Net Entity Framework IEntityChangeTracker의 여러 인스턴스에서 엔터티 개체를 참조 할 수 없습니다” 라는 예외가 발생 합니다.
나는 많은 게시물을 읽었지만 여전히해야 할 일에 대한 정확한 아이디어를 얻지 못했습니다 … 저장 버튼 클릭 코드는 다음과 같습니다.
protected void Button1_Click(object sender, EventArgs e)
{
EmployeeService es = new EmployeeService();
CityService cs = new CityService();
DateTime dt = new DateTime(2008, 12, 12);
Payroll.Entities.Employee e1 = new Payroll.Entities.Employee();
Payroll.Entities.City city1 = cs.SelectCity(Convert.ToInt64(cmbCity.SelectedItem.Value));
e1.Name = "Archana";
e1.Title = "aaaa";
e1.BirthDate = dt;
e1.Gender = "F";
e1.HireDate = dt;
e1.MaritalStatus = "M";
e1.City = city1;
es.AddEmpoyee(e1,city1);
}
및 직원 서비스 코드
public string AddEmpoyee(Payroll.Entities.Employee e1, Payroll.Entities.City c1)
{
Payroll_DAO1 payrollDAO = new Payroll_DAO1();
payrollDAO.AddToEmployee(e1); //Here I am getting Error..
payrollDAO.SaveChanges();
return "SUCCESS";
}
답변
이 두 줄 때문에 …
EmployeeService es = new EmployeeService();
CityService cs = new CityService();
… 생성자에 매개 변수를 사용하지 마십시오. 클래스 내에 컨텍스트를 생성한다고 생각합니다. 로드 할 때 city1
…
Payroll.Entities.City city1 = cs.SelectCity(...);
… city1
의에 컨텍스트 를 첨부합니다 CityService
. 나중에 city1
새 참조에 대한 참조로 Employee
e1
추가 e1
하고이 참조를 포함city1
하여의 컨텍스트에 추가 EmployeeService
합니다. 결과적으로 city1
예외가 불평하는 두 가지 다른 컨텍스트에 첨부되었습니다.
서비스 클래스 외부에서 컨텍스트를 작성하고 두 서비스 모두에서 컨텍스트를 삽입하고 사용하여이 문제를 해결할 수 있습니다.
EmployeeService es = new EmployeeService(context);
CityService cs = new CityService(context); // same context instance
서비스 클래스는 단일 엔터티 유형 만 담당하는 리포지토리와 비슷합니다. 이 경우 서비스에 별도의 컨텍스트를 사용할 때 엔티티 간의 관계가 시작 되 자마자 항상 문제가 발생합니다.
또한 EmployeeCityService
(단일 컨텍스트가있는) 밀접하게 관련된 엔티티 세트를 담당하는 단일 서비스를 작성하고 Button1_Click
메소드 의 전체 조작 을이 서비스의 메소드에 위임 할 수도 있습니다.
답변
재현 단계는 다음과 같이 단순화 할 수 있습니다.
var contextOne = new EntityContext();
var contextTwo = new EntityContext();
var user = contextOne.Users.FirstOrDefault();
var group = new Group();
group.User = user;
contextTwo.Groups.Add(group);
contextTwo.SaveChanges();
오류없는 코드 :
var context = new EntityContext();
var user = context.Users.FirstOrDefault();
var group = new Group();
group.User = user; // Be careful when you set entity properties.
// Be sure that all objects came from the same context
context.Groups.Add(group);
context.SaveChanges();
하나만 사용하면 EntityContext
이 문제를 해결할 수 있습니다. 다른 솔루션에 대해서는 다른 답변을 참조하십시오.
답변
이것은 오래된 스레드이지만 선호하는 또 다른 솔루션은 cityId를 업데이트하고 구멍 모델 City를 Employee에 할당하지 않는 것입니다.
public class Employee{
...
public int? CityId; //The ? is for allow City nullable
public virtual City City;
}
그런 다음 충분하게 할당하십시오.
e1.CityId=city1.ID;
답변
주입 및 더 나쁜 Singleton 대신 Add 전에 Detach 메서드를 호출 할 수 있습니다 .
엔티티 프레임 워크 6 : ((IObjectContextAdapter)cs).ObjectContext.Detach(city1);
EntityFramework 4 : cs.Detach(city1);
첫 번째 DBContext 객체가 필요하지 않은 경우 다른 방법이 있습니다. 키워드 를 사용하여 감싸십시오 .
Payroll.Entities.City city1;
using (CityService cs = new CityService())
{
city1 = cs.SelectCity(Convert.ToInt64(cmbCity.SelectedItem.Value));
}
답변
나는 같은 문제가 있었지만 @Slauma의 솔루션에 대한 내 문제 (특정 인스턴스에서는 크지 만)는 컨텍스트를 서비스에 전달하여 컨트롤러에서 컨텍스트를 사용할 수 있음을 암시하는 것이 좋습니다. 또한 컨트롤러와 서비스 계층간에 긴밀한 연결을 강제합니다.
서비스 / 리포지토리 레이어를 컨트롤러에 주입하기 위해 Dependency Injection을 사용하고 있으므로 컨트롤러의 컨텍스트에 액세스 할 수 없습니다.
내 솔루션은 서비스 / 리포지토리 레이어가 동일한 컨텍스트 인스턴스 인 Singleton을 사용하도록하는 것입니다.
컨텍스트 싱글턴 클래스 :
참조 : http://msdn.microsoft.com/en-us/library/ff650316.aspx
및 http://csharpindepth.com/Articles/General/Singleton.aspx
public sealed class MyModelDbContextSingleton
{
private static readonly MyModelDbContext instance = new MyModelDbContext();
static MyModelDbContextSingleton() { }
private MyModelDbContextSingleton() { }
public static MyModelDbContext Instance
{
get
{
return instance;
}
}
}
리포지토리 클래스 :
public class ProjectRepository : IProjectRepository
{
MyModelDbContext context = MyModelDbContextSingleton.Instance;
[...]
컨텍스트를 한 번 인스턴스화하여 서비스 / 저장소 계층의 생성자 또는 작업 단위 패턴을 구현하는 다른 솔루션으로 전달하는 것과 같은 다른 솔루션이 있습니다. 더 많은 것이 있다고 확신합니다 …
답변
필자의 경우 ASP.NET Identity Framework를 사용하고있었습니다. 엔티티 UserManager.FindByNameAsync
를 검색하기 위해 내장 메소드를 사용했습니다 ApplicationUser
. 그런 다음 다른 엔터티에서 새로 만든 엔터티에서이 엔터티를 참조하려고했습니다 DbContext
. 이로 인해 원래 본 예외가 발생했습니다.
메소드 ApplicationUser
에서만 Id
from을 사용하여 새 엔티티를 작성하고 UserManager
해당 새 엔티티를 참조 하여이를 해결했습니다 .
답변
나는 같은 문제가 있었고 업데이트하려고하는 객체의 새 인스턴스를 만들 수 있습니다. 그런 다음 그 대상을 내 철학자에게 전달했습니다.
