2012-10-24 5 views
1

처음에는 ADO.NET, LINQ 및 해당 데이터 액세스 기술에 익숙하지 않습니다. 인터넷에서 읽고 읽은 바를 이해하는 한 LINQ2SQL은 ADO.NET으로 발전한 엔티티에 LINQ로 진화했습니다. 어쩌면 나는 그 개념들에 대해 잘못 알고있다.ADO.NET에서 생성 된 엔티티를 업데이트하는 동안 ObjectContext 개체에 액세스하는 방법

지금 질문드립니다. 나는 학교를 관리하기 위해 ADO.NET을 사용하여 VS2010 (.NET 4.0) 시스템을 개발 중입니다. 솔루션은 Presentation Layer (GUI 만 가능), Bussiness Layer (모든 프로세스는 여기에서), Data Layer (쿼리 및 데이터베이스 액세스 만)의 세 가지 레이어로 나뉩니다.

데이터베이스에는 현재 모든 국가가 포함 된 국가 테이블에 대한 참조를 저장하는 국적 필드가있는 사람 (학생, 교사, 행정직 등)의 데이터를 저장하는 사람이 있습니다.

첫 번째 접근 방식에서는 연결 문자열과 데이터베이스 모델 (ADO.NET 엔터티 데이터 모델 디자이너에서 생성 한 코드)에 대한 참조를 저장하는 ConnectionManager라는 단일 클래스를 만들었습니다.이 개체는 ObjectContext에서 상속받은 개체입니다. SystemEntities.

이 시점에서 모든 것이 잘되었지만, 다음 시나리오에 대해 궁금해했습니다. 사용자가 대출에 도달하면 개인 정보를 편집하고 지불을 위해 청구서를 요청합니다. 사용자는 청구서 양식으로 전환하고 인쇄하기 전에 데이터를 채우고 저장합니다. 이 과정에서 SystemEntities.SaveChanges에 대한 호출이 이루어 지므로 모든 변경 내용이 데이터베이스에 저장되고 편집되지 않은 변경 내용이 저장되지만 바람직하지 않은 동작입니다.

그런 다음 데이터베이스 연결을 유지하는 싱글 톤이 없어야한다는 것을 알았습니다. 모든 ObjectContext는 데이터를 가져온 후에 삭제되므로이 코드를 사용하십시오. 나는 사람의 국가를 변경 구체적으로, 사람을 편집하려고 할 때

public static T[] QueryAll<T>() where T : Person 
{ 
    using (SystemEntities context = ConnectionManager.Instance.GetContext()) 
    { 
     return context.People 
      .OfType<T>() 
      .Include("Emails") 
      .Include("Phones") 
      .OrderBy(affiliate => affiliate.LastName + " " + affiliate.FirstName) 
      .ToArray(); 
    } 
} 

는 국가

public static Country GetByID(string id) 
{ 
    using (SystemEntities context = ConnectionManager.Instance.GetContext()) 
    { 
     return context.Countries.FirstOrDefault(country => country.CountryID == id); 
    } 
} 
이제

를 가져 오는 모든 사람들을 인출하려면, 예외가 오르지한다 :

The relationship between the two objects cannot be defined 
because they are attached to different ObjectContext objects. 

다음과 같은 코드를 통해 수행됩니다

public Person Person 
{ 
    get { ... } 
    set 
    { 
     this.person = value; 
     ... 
     this.cmbNationality.DataBindings.Add("SelectedItem", person, "Nationality"); 
     this.cmdAddressCountry.DataBindings.Add("SelectedItem", person, "Country"); 
     ... 
    } 
} 

private void form_Load(object sender, EventArgs e) 
{ 
    Country[] countries = Country.QueryAll(); 
    Country mexico = Country.GetByA2("MX"); 
    this.cmbNationality.DataSource = countries; 
    this.cmdAddressCountry.DataSource = countries; 
    this.cmbNationality.SelectedItem = mexico; 
    this.cmdAddressCountry.SelectedItem = mexico; 
} 

그래서 cmbNationality 및 cmdAddressCountry 콤보 상자에서 항목을 변경하면 예외가 throw됩니다. 이 변경 사항은 변경 사항 일 뿐이며 저장은 수행되지 않았습니다.

필자가 이해하는 한, 이것은 Person 및 Country 객체가 다른 SystemEntities (ObjectContext) 객체의 데이터베이스에서 가져 오기 때문에 생성됩니다.

그리고 문제 및 질문이 있습니다. 싱글 톤을 사용할 수없고 사용 후 모든 컨텍스트를 처리해야한다면 어떻게 해결할 수 있습니까? 물론 손으로 업데이트하거나 데이터 바인딩을 사용하지 않기 위해이 문제를 피할 수있는 몇 가지 방법을 만들 수 있습니다. 업데이트를해야 할 경우 ADO.NET의 요점은 무엇입니까?

어쩌면 어리 석거나 사소한 것일 수도 있습니다 (또는 방금 답을 찾는 방법을 모를 수도 있습니다). 그러나 답을 찾을 수 없었습니다.사전에

감사

답변

1

같은

SystemEntities (ObjectContext) objects. 

을 얻을 것이다, 그래서 나는 그것을 희망

"context = ConnectionManager.Instance.GetContext()" \ 생성자의 사용 golbal 객체 클래스 "SystemEntities 컨텍스트"때를 설정하지 왜 당신을 도울 수 있어요.

+0

OP는 이미 싱글 톤 컨텍스트를 가지며 그 패턴에서 벗어나려고합니다. –

1

표준 연결이 끊어진 모델을 사용하는 것 같습니다. 연결이 끊어 졌으므로 수정 된 객체를 유지할 때마다 현재 컨텍스트에서 엔티티를 다시 수화해야합니다. 다음은 내가 말하고자하는 바를 잘 보여줍니다.

public static Person PersistPerson(Person person) 
    { 
     using (SystemEntities context = ConnectionManager.Instance.GetContext()) 
     { 
      bool doInsert = false; 
      var p = context.People.Where(d => d.PersonId == person.PersonId).FirstOrDefault(); 
      if (p == null) 
      { 
       p = new Person(); 
       doInsert = true; 
      } 

      //update connected Entity 
      p.LastName = person.LastName; 
      p.Emails = person.Emails; 
      //etc... 
      if(doInsert)      
       context.People.AddObject(person); 

      context.SaveChanges(); 
      person.PersonId = p.PersonId; 
     } 
     return person; 
    } 
+0

사실 나는 SP와 함께 그 접근법을 시도했다. 문제는 데이터베이스에 저장할 때조차도 그 지점에 도달 할 수 없다는 것입니다. 문제는 사람 p가 있는데 다음과 같은 경우입니다. 'p.Nationality = (Country) comboBox.SelectedItem;' comboBox는 peron의 컨텍스트와 다른 컨텍스트에서 오는 Country 객체의 배열로 데이터 바운딩을 통해 채워지기 때문에 할당 중에 오류가 발생합니다. – Kyordhel

+0

음, 이것은 우아하게 보이지 않을 수도 있지만, 실제 Person 테이블에 NationalityId가 있다고 가정합니다.이 경우 Person 엔티티에 해당 Id 속성을 설정할 수 있습니다 (예 : p.NationalityId = Country.CountryId). 이것은 동시에 데이터베이스에 새 Country를 추가하지 않는다고 가정합니다. 즉 Country가 null이 아닌 경우 CountryId는 항상 값을 갖습니다. –

+0

예, 데이터베이스에는 해당 FK가있는 국적 필드 (국가 테이블의 국가를 나타내는 CountryID)가 있습니다. 그러나 ADO.NET은 ID로 국적을 추가하지는 않지만 국가 개체를 추가하므로 국적을 변경하려는 경우 참조 된 고유 한 CountryID가있는 Country 개체를 변경하면 ADO.NET에서 해당 값을 업데이트 할 수 있습니다. 데이터베이스 전체 프로젝트에 대해 단일 컨텍스트를 사용하고 닫지 않는 경우 잘 작동하지만 컨텍스트를 만들고 닫으면 연결이 닫히고 예외가 발생합니다. – Kyordhel

관련 문제