0

배경 : XML 파일 (전자 서명 이벤트 정보)을 구문 분석하고 Entity Framework Code First를 통해 구문 분석 된 데이터를 기반으로 데이터베이스 레코드를 만들려고합니다. (Entity Framework Power Tools Beta 3의 도움으로).도메인의 참조 무결성을 존중하도록 엔터티를 가져올 수 없습니다.

using (var context = new BSContext()) 
{ 
    foreach (var e in events) 
    { 
     try 
     {      
      // Create the Author Entity 
      var AuthorEntity = parser.getAuthorByName(e.Author); 
      if (AuthorEntity == null) 
      { 
       AuthorEntity = new Author() 
       { 
        Name = e.Author 
       }; 
       context.Authors.Add(AuthorEntity); 
       context.SaveChanges(); 
      }       


      // Create the Location Entity 
      var LocationEntity = parser.getLocationByNameAddressAndPostCode(e.Location.Name, e.Location.Address, e.Location.PostCode); 
      if (LocationEntity == null) 
      { 
       LocationEntity = new Location() 
       { 
        Name = e.Location.Name, 
        Address = e.Location.Address, 
        City = e.Location.City, 
        County = e.Location.County, 
        PostCode = e.Location.PostCode, 
        Telephone = e.Location.Telephone 
       }; 
       context.Locations.Add(LocationEntity); 
       context.SaveChanges(); 
      }       


      // Create the Book Entity 
      var BookEntity = parser.getBookByName(e.Book.Name); 
      if(BookEntity == null) 
      { 
       BookEntity = new Book() 
       { 
        Name = e.Book.Name, 
        BookImgUrl = e.Book.BookImgUrl 
       }; 
       context.Books.Add(BookEntity); 
       context.SaveChanges(); 
      } 


      // Create the Event Entity 
      string dtObjFormat = "dd MMM yyyy HH:mm"; 
      DateTime dt; 
      var EventEntity = new Event() 
      { 
       Author = AuthorEntity, 
       Book = BookEntity, 
       Info = e.Info, 
       Start = DateTime.TryParseExact(e.Date + " " + e.Time, dtObjFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out dt) ? dt : new DateTime(), 
       Location = LocationEntity 
      }; 
      context.Events.Add(EventEntity); 
      context.SaveChanges(); 
     } 
     catch 
     { 
      Console.WriteLine("Something went wrong!"); 
     } 
    } 
    Console.WriteLine("Looped through all Events"); 
} 

위의 코드, 엔티티를 생성하고 데이터베이스에 저장하려고 시도합니다 :

구문 분석 로직을 정렬 후, 나는 데이터베이스에 분석 된 데이터를 저장하기위한 다음과 같은 코드가 있습니다. 필요가 생기면 저장된 엔티티를 다시 사용하십시오.

예를 들어 XML 파일 에 저자가 두 번 나타나지만 해당 작성자의 이전 루프에서 이미 레코드를 만들었으므로 해당 작성자의 레코드 두 개를 만들지는 않습니다.입니다. 비록 내 마음에 나는 그것을 처리하는 코드를 가지고 있지만 (위 참조), 그것은 여전히 ​​여러 가지 저자 레코드를 생성합니다. 책에도 똑같은 문제가 있습니다.

/// <summary> 
/// A method to get an Author Entity by name. If no Author exists, then 
/// NULL is returned. If two authors exist with the exact same name, 
/// then the first encountered is returned. 
/// </summary> 
/// <param name="authorName">The name of the Author.</param> 
/// <returns>The Author Entity</returns> 
public Author getAuthorByName(String authorName) 
{ 
    using (var context = new BSContext()) 
    { 
     return context.Authors.FirstOrDefault(x => x.Name == authorName); 
    } 
} 

두 개의 다른 방법 및 getBookByName(String bookName)getLocationByNameAddressAndPostCode(String lName, String lAddress, String lPostCode) 모두 상기 방법과 유사한 로직을 가지고

getAuthorByName(String authorName) 방법은 다음의 코드를 갖는다.

문제점 : 엔티티 Book 및 Author에 대한 데이터베이스의 레코드 중복을 중지하십시오.

답변

1

여기서주의해야 할 것은 사용중인 2 개의 활성 BSContext 개체가 있다는 것입니다. 엔티티 추적은 이러한 각 컨텍스트에서 개별적으로 발생합니다. Aka Author는 둘 다에서 살며, 둘 다에서 쿼리하지 않는 한 둘 다 살 수 없습니다.

일단 getAuthorByName 메소드를 완료하면 작성자 엔티티가 모든 엔티티 컨텍스트에서 분리됩니다. 이 엔티티를 외부 컨텍스트 (최상위 코드 예제의 일명)에 다시 첨부하면됩니다. 위 코드에서와 같이 BSContext는 이것이 기존 엔티티임을 인식하지 못하고 새로운 엔티티라고 믿는다. 새 저자가 데이터베이스에 삽입됩니다.

또는 대신이 작업을 시도해 볼 수 있습니다.

/// <summary> 
/// A method to get an Author Entity by name. If no Author exists, then 
/// NULL is returned. If two authors exist with the exact same name, 
/// then the first encountered is returned. 
/// </summary> 
/// <param name="authorName">The name of the Author.</param> 
/// <returns>The Author Entity</returns> 
public Author getAuthorByName(BSContext context, String authorName) 
{ 
     return context.Authors.FirstOrDefault(x => x.Name == authorName); 
} 

그리고 파서 같은

var AuthorEntity = parser.getAuthorByName(context, e.Author); 
+0

잘 만든 점에 문의하십시오. 나는 그것에 대해 완전히 잊었다. 감사합니다 Alistair, 이제 작동합니다.^_ ^ – Ciwan

관련 문제