LINQ to ENTITIES : 엔티티, 엔티키, 첨부 및 새 개체의 혼합 그래프
-
06-07-2019 - |
문제
내 데이터 모델에는 객체/테이블/데이터 사이에 상당히 일반적인 분할이 있습니다.
- 시스템이 수행하는 작업을 나타내는 "트랜잭션"엔티티. 이러한 엔티티는 시스템에 의해 생성되며 특정 상황에서만 중요합니다. 그들은 정기적으로 즉시 만들어집니다. (제외 :이 유형의 엔티티에 적절한 이름이 있습니까?)
- 트랜잭션 엔티티의 공통 속성을 나타내는 "데이터 사전"엔티티. 이것들은 불규칙적으로 (주로 프로젝트 시작시) 정의되어 있으며 훨씬 더 정적 수명주기를 가지고 있습니다. 그들은 일반적으로 나에 의해 만들어집니다.
예를 들어, 사용자 (트랜잭션) 엔티티와 사용자 유형 (데이터 사전) 엔티티가있을 수 있습니다.
데이터 사전 엔티티의 인스턴스에 대한 (하드) 코드 참조를 내 코드에 넣고 싶습니다. 이것은 이해하기 쉬운 언어로 비즈니스 논리를 코딩 할 수있는 능력을 제공합니다. (예를 들어, "일반"의 사용자 유형과 "admin"의 사용자 유형이있을 수 있으며, "사용자의 사용자 유형이 admin과 동일하면 액세스 허용"이라는 규칙이있을 수 있습니다.
Data Access Technology/ORM으로 LINQ-to-Enties를 사용하고 있습니다. 데이터 사전 참조를 구현하기 위해 EntityKeys를 저장하고 있습니다. 내 이해는 객체 컨텍스트에서 분리되어 있어이 목적에 적합하다는 것입니다. (그들은 단체 상태를 포함하지 않기 때문에 그 상태가 부실한 것에 대해 걱정할 필요가 없습니다.)
그러나 이것은 DD-EntityKey-Reference와 함께 새로운 트랜잭션 엔티티를 추가하려고 할 때 문제를 일으킨다. 내 예를 계속하고 있습니다. 저는 이것을하고 있습니다.
UserEntities userEntities = new UserEntitites()
User user = new User()
user.UserType = new UserType()
user.UserType.EntityKey = adminEntityKey
userEntities.AddToUser(user)
... 그리고 이것은 다음과 같은 오류를줍니다.
System.InvalidOperationException : 객체는 EntityKey가 이미 있으므로 ObjectStateManager에 객체를 추가 할 수 없습니다. ObjectContext.attach를 사용하여 기존 키가있는 개체를 첨부하십시오.
AddTouser 대신 userentities.attach (사용자)를 호출하려고하면 다음과 같이받습니다.
System.InvalidOperationException : NULL ENTITYKEY 값을 가진 개체는 객체 컨텍스트에 첨부 할 수 없습니다.
내가하고있는 신규 및 기존 개체의 혼합을 감안할 때이 두 오류는 모두 의미가 있습니다. 내가 확실하지 않은 것은이 문제를 해결하는 방법입니다. DD- 엔티티에 대한 언급을 분리하고 전체 DD- 엔티티 상태를로드 할 필요없이 새로운 첨부 된 개체에 할당 할 수있는 방법이 있습니까?
해결책
왜 예외를 얻는 지 설명하려고 노력할 것입니다.
System.InvalidOperationException : 객체는 EntityKey가 이미 있으므로 ObjectStateManager에 객체를 추가 할 수 없습니다. ObjectContext.attach를 사용하여 기존 키가있는 개체를 첨부하십시오.
새로운 사용자 및 사용자 유형 엔티티가 작성되었습니다. userType의 EntityKey가 설정되었지만 UserEntities.Add () EF가 추가 된 상태를 설정하려고 시도하면 추가되었습니다. userType에는 EntityKey가 있으므로 EF는 무언가 잘못되었음을 깨닫고 예외를 던졌습니다.
System.InvalidOperationException : NULL ENTITYKEY 값을 가진 개체는 객체 컨텍스트에 첨부 할 수 없습니다.
이 예외에서는 사용자 유형에서는 모든 것이 괜찮지 만 사용자 엔티티는 EntityKey가 없으므로 첨부 할 수 없기 때문에 예외가 발생합니다.
이것이 제가이 문제를 해결하는 방법입니다 (데이터 사전 참조의 하드 코딩이 괜찮다면) :
userType 엔티티에서 userType ID에 대한 정적 참조를 작성합니다.
public partial class UserType
{
public const int AdminUserTypeID = 1;
public const int PlainUserTypeID = 2;
}
사용자 엔티티에는 Extender 속성이있어 사용자 유형 이외의 키에 쉽게 액세스 할 수 있습니다.
public partial class User
{
public int? UserTypeID
{
set
{
UserTypeReference.EntityKey = new EntityKey("UserEntities.UserType", "UserTypeID", value);
}
get
{
if (UserTypeReference.EntityKey == null)
return null;
if (UserTypeReference.EntityKey.EntityKeyValues.Count() > 0)
return (int)UserTypeReference.EntityKey.EntityKeyValues[0].Value;
else
return null;
}
}
}
마지막으로, 새 사용자를 생성하기위한 유스 케이스는 다음과 같습니다.
using(UserEntities userEntities = new UserEntitites())
{
User user = new User();
user.UserTypeID = UserType.AdminUserTypeID;
userEntities.AddToUser(user);
userEntities.SaveChanges()
}