2010-04-27 1 views
1

다른 질문과 유사한 오류가 발생하지만 완전히 동일하지는 않습니다. 아무 것도 첨부하려고하지 않습니다."다른 DataContext에서로드되지 않은 엔티티를 첨부하거나 추가하십시오. 이것은 지원되지 않습니다." 링커 개체 삽입시 문제가 발생했습니다.

내가하려고하는 작업은 연결 테이블에 UserAccomplishment라는 새 행을 삽입하는 것입니다. 관계는 LINQ에서 사용자 및 성과 표로 설정됩니다.

나는 일반적인 삽입 기능이 있습니다
Public Function insertRow(ByVal entity As ImplementationType) As Boolean 
     If entity IsNot Nothing Then 

      Dim lcfdatacontext As New LCFDataContext() 
      Try 
       lcfdatacontext.GetTable(Of ImplementationType)().InsertOnSubmit(entity) 

       lcfdatacontext.SubmitChanges() 
       lcfdatacontext.Dispose() 
       Return True 
      Catch ex As Exception 
       Return False 
      End Try 
     Else 
      Return False 
     End If 
End Function 

당신이 시도하고 UserAccomplishment에게 사용자 또는 성취 중 하나가 이미 존재하는 경우이 자연스럽게 똥 것이 적절한 오브젝트를주는 경우에

. 사용자와 성취도가 모두 존재하지 않는 경우에만 작동합니다. 나는이 행동을 기대했다. 작업은 단순히 userAccomplishment 객체에 user.id 및 accomplishment.id를 제공하고 나머지 필드를 채우는 것입니다. 이 작동하지만 내 애플 리케이션에서 사용하기 위해 일종의 어색한, 그것은 단순히 두 개체를 전달하고 이미 존재하지 않는 것을 밖으로 작동하도록 훨씬 쉬울 것이다. 제공된 사용자와 성취가 이미 DB에있는 경우 기본적으로 내가 확인 여기,

Public Class UserAccomplishmentDao 
    Inherits EntityDao(Of UserAccomplishment) 

    Public Function insertLinkerObjectRow(ByVal userAccomplishment As UserAccomplishment) 

     Dim insertSuccess As Boolean = False 

     If Not userAccomplishment Is Nothing Then 

      Dim userDao As New UserDao() 
      Dim accomplishmentDao As New AccomplishmentDao() 
      Dim user As New User() 
      Dim accomplishment As New Accomplishment() 


      'see if either object already exists in db' 
      user = userDao.getOneByValueOfProperty("Id", userAccomplishment.User.Id) 
      accomplishment = accomplishmentDao.getOneByValueOfProperty("Id", userAccomplishment.Accomplishment.Id) 


      If user Is Nothing And accomplishment Is Nothing Then 
       'neither the user or the accomplishment exist, both are new so insert them both, typical insert' 
       insertSuccess = Me.insertRow(userAccomplishment) 

      ElseIf user Is Nothing And Not accomplishment Is Nothing Then 
       'user is new, accomplishment is not new, so just insert the user, and the relation in userAccomplishment' 
       Dim userWithExistingAccomplishment As New UserAccomplishment(userAccomplishment.User, userAccomplishment.Accomplishment.Id, userAccomplishment.LastUpdatedBy) 
       insertSuccess = Me.insertRow(userWithExistingAccomplishment) 
      ElseIf Not user Is Nothing And accomplishment Is Nothing Then 
       'user is not new, accomplishment is new, so just insert the accomplishment, and the relation in userAccomplishment' 
       Dim existingUserWithAccomplishment As New UserAccomplishment(userAccomplishment.UserId, userAccomplishment.Accomplishment, userAccomplishment.LastUpdatedBy) 
       insertSuccess = Me.insertRow(existingUserWithAccomplishment) 
      Else 
       'both are not new, just add the relation' 
       Dim userAccomplishmentBothExist As New UserAccomplishment(userAccomplishment.User.Id, userAccomplishment.Accomplishment.Id, userAccomplishment.LastUpdatedBy) 
       insertSuccess = Me.insertRow(userAccomplishmentBothExist) 
      End If 

     End If 

     Return insertSuccess 

    End Function 

End Class 

좋아, 그리고 경우 : 그래 그래서 (나는 그것이 알고 있기 때문에이 끔찍하게 비효율적이라는 사실을 무시하십시오) 다음 만든 그래서 이미 존재하는 것은 무엇이든 남겨 둘 수있는 적절한 생성자를 호출하지만 삽입이 성공할 수 있도록 나머지 정보를 제공하십시오.

그러나, 삽입 시도에 :

"An attempt has been made to Attach or Add an entity that is not new, perhaps having been loaded from another DataContext. This is not supported." 

I :

Dim result As Boolean = Me.userAccomplishmentDao.insertLinkerObjectRow(userAccomplishment) 

하는 사용자가 이미 존재하지만 성취하지 않는를합니다 (99 % 일반적인 시나리오) 나는 오류 지금이 여러 번 디버깅을하고 이것이 발생하는 이유를 확신하지 못합니다. User 또는 Accomplishment가있는 경우이를 삽입하려고 시도하는 최종 개체에 포함하지 않을 것입니다. 그래서 아무것도 추가하려고 시도하지 않는 것처럼 보입니다. 디버그에서도 삽입시 객체가 비어있게 설정되었습니다. 따라서 성취는 새 것이며 사용자는 비어 있습니다.

1) 왜 아직도 그 말을하고 어떻게 내가 내 현재의 구조를 ..using 해결할 수

2) 선제 '응답 저장소 패턴을 사용하는'-이 방법은 가지 일반적으로 짜증 알고 저장소 패턴을 사용해야합니다. 그러나, 현재 프로젝트에서 사용할 수 없습니다. 왜냐하면 저는 리팩터링 할 시간이 없기 때문입니다. 응용 프로그램의 사용법이 너무 작아서 데이터 인터페이스의 비효율적 인 사용과 그다지 중요하지 않은 부분이 있습니다. 한번 리팩토링 할 수는 있지만, 현재로서는 현재 구조로 '밀어 넣기'만하면됩니다.

편집 : 또한 두 가지가 이미 존재하고 각 개체의 ID를 해당 테이블에 삽입하면 작동합니다. 그래서 내가 수동으로 하나의 삽입으로 존재하지 않는 개체를 삽입 할 수있을 것 같아요 다음 ID를 연결 테이블에 넣어,하지만 난 여전히 왜 하나의 개체가 존재하는지, 그리고 그것을 비워, doens ' 일하지 마라.

답변

2

무엇보다 먼저 열심히 노력하고 있다고 생각하지만 이해할 수 있습니다.

내가하려는 일을 이해했는지 보자. 사용자 및 성과를 추적하는 연결 표를 업데이트하려고합니다.사전에 존재하는 것에 관계없이, 끝내면 유효한 UserAccomplishment 레코드가 필요하며, 성취되고 유효한 관계가 완성됩니다. 이제 시작하자 :

public void AddUserAccomplishment(user User, accomplishment Accomplishment) 
{ 
    using (LCFDataContext dc = new LCFDataContext()) 
    { 
     // Substitute <UserName> for any other unique field in the record. 
     var tempUser = dc.Users 
      .Where(a => a.UserName.ToLower() == user.UserName.ToLower()) 
      .SingleOrDefault(); 

     // Using SingleOrDefault() creates an empty User entity object if 
     // a matching record can't be found, which means the Id field will 
     // be equal to zero. 
     if (tempUser.Id == 0) 
     { 
      // Populate the empty tempUser entity object 
      tempUser.UserName = user.UserName; 
       . 
       . 
       . 
      dc.Users.InsertOnSubmit(tempUser); 
     } 

     // Do the same thing for the Accomplishment. 
     var tempAccomplishment = dc.Accomplishments 
      .Where(a => a.Title.ToLower() == accomplishment.Title.ToLower()) 
      .SingleOrDefault(); 

     if (tempAccomplishment.Id == 0) 
     { 
      // Populate the empty tempAccomplishment entity object 
      tempAccomplishment.Title = accomplishment.Title; 
       . 
       . 
       . 
      dc.Accomplishments.InsertOnSubmit(tempAccomplishment); 
     } 

     // Now, you need to make sure that the UserAccomplishment entity object 
     // doesn't already exist. 
     if (dc.UserAccomplishments 
      .Where(a => a.User.Id == tempUser.Id 
       && a.Accomplishment.Id == tempAccomplishment.Id) 
      .Count == 0) 
     { 
      UserAccomplishment userAccomplishment = new UserAccomplishment(); 

      userAccomplishment.User = tempUser; 
      userAccomplishment.Accomplishment = tempAccomplishment; 
      dc.UserAccomplishments.InsertOnSubmit(userAccomplishment); 
     } 
     else 
     { 
      // The UserAccomplishment record already exists, so throw an 
      // exception or display an error message. 
     } 

     dc.SubmitChanges();  
    } 
} 

이 도움이되는지 알려주세요 ...

+0

감사 닐 T.이 마법처럼 일했다, 그래 당신은 조금 더 쉽습니다. 나는 제네릭 함수를 사용하기에는 너무 열심히 노력하지만, 다른 dataContexts를 얻는다면 문제가 발생합니다. dataContext 핸들을 얻는 것은 여전히 ​​어렵습니다. – SventoryMang

+0

개인적으로 저는 단일 DataContext를 사용하는 것을 선호합니다. 현재 웹 프로젝트에는 M-M 관계가 몇 개 이상있는 약 60-70 개의 테이블이 있습니다. 여러 DataContext 사이의 활동을 조정하려고하는 것은 재미 있지 않을 것입니다 ... 여러 DC를 갖는 것에 대해 계속 듣고있는 (그러나 목격 한 적이없는) 이익을 얻으려면 적어도 현재 DC를 적어도 8-10 더 작은 DCs. 나는 그 수준의 세밀도를 관리하려고하지도 않습니다. –

+0

DAL 레이어에 작성된 모든 함수는 위와 같이 사용합니다. 또는 저장소 패턴을 사용하고 있습니까? 한 가지 문제는 (내가 생각하기에) 저장소 패턴과 함께 사용하는 클래스는 using 문으로 호출되어야한다는 것입니다.하지만 어떻게 작동합니까? 그러면 page_load에서 일부 개체를 가져온 다음 어떻게 저장합니까? 버튼을 클릭 하시겠습니까? 또한 내가 명확하지 않을 수도 있지만 원래의 의견에서 나는 다른 dataContext 인스턴스를 의미했다. 그것은 당신이 다른 dataConext 클래스를 가지고있는 것처럼 들렸다. – SventoryMang

관련 문제