4

데이터 모델에서 일부 테이블 당 상속을 구현했습니다. 기본적으로 내 항목에 대한 모든 기본 정보가있는 BaseEntity 형식과 BaseEntity 항목에서 상속되는 Employer 형식이 있습니다. 모든 것이 올바르게 설정되어있는 것처럼 보입니다. Entity (ADO.net Data Services 또는 Linq to Entities를 통해)를 사용할 때 Employer 유형을 볼 수 있으며 문제가없는 것처럼 보입니다. 새 Employer 엔터티를 만들고 저장하려고하면 문제가 시작됩니다.Entity Framework를 저장할 수 없습니다. 상속 된 형식

.AddToEmployer 항목과 일치하지 않는 문맥에서만 (AddObject 또는 AddToBaseEntity)

내가 AddObject("Employer", NewEmployer)를 사용하는 경우 내가 얻을 오류 메시지 :

이 EntitySet 이름 'DataEntities.Employer이'

를 찾을 수 없습니다. 종속 작업을위한 올바른 순서를 확인할 수 없습니다

: 나는 AddToBaseEntity(NewEmployer)를 사용하는 경우

나는의 오류 메시지가 표시됩니다. 외부 키 제한 조건, 모델 요구 사항 또는 스토어 생성 값으로 인해 종속성이있을 수 있습니다.

상속 설정 단계가 빠졌습니까? 상속 된 객체를 저장하는 특정 방법이 있습니까? 내가 도대체 ​​뭘 잘못하고있는 겁니까? 기본 문제는 내가 AddToEmployer을 가져야한다고 가정합니다. 노출되도록하려면 어떻게해야합니까? 클라이언트 측에서 고용주 유형을 볼 수 있고 다음과 같은 일을 할 수 있기 때문에 옵션이 아니라는 것이 이상하게 보입니다.

var NewEmployer = new Employer() - 저는 고용주 유형을 잘 볼 수 있다고 생각하는 것 같습니다.

답변

2

나는 몇 가지를 바꿔서 이것을 작동시킬 수있었습니다. 나는 근본적인 문제가 무엇인지 확실하지 않지만, 내가 한 일을 참조로 게시하고 싶었다.

재구성 된 테이블 : ID/키 열과 단일 데이터 열로 시작하는 테이블을 재구성했습니다.

제거 된 추가 자동 증가 필드 : BaseEntity와 Employer에 자동 증가 ID가 있습니다. Employer에서 자동 증가 ID를 제거하고 Employer.BaseEntityID 열과 외래 키를 BaseEntity.BaseEntityID로 다시 가져 왔습니다. (이것은 범인 인 것처럼 보였지만 이것이 허용 된 것처럼 보였습니다.)

불행하게도 엔티티 프레임 워크에서 enherited 클래스는 탐색 속성을 가질 수 없다는 문제를 야기합니다 (모든 탐색 속성은 기본 엔티티)가 필요하므로 상속을 사용하지 못하게 될 것입니다.

1

엔터티 유형과 마찬가지로 엔터티 집합으로 정의 된 고용주가 없습니다. 이것이 컨텍스트 객체에서 AddToEntity가 누락 된 방식입니다. 하나의 클래스 계층 구조에 대해 항상 하나의 엔티티 집합이 있습니다.이 경우 BaseClass 엔티티 집합입니다.

엔티티 세트 '고용주'를 얻으려면 edmx 파일을 수동으로 편집하고 새로운 엔티티 세트 '고용주'를 추가 한 다음 엔티티 유형 '고용주'를 해당 엔티티 세트에 속하도록 설정하십시오. 그것은 어렵지 않아야합니다, 나는 그것을 많이했습니다.

좀 더 일반적인 해결책이 있는지 확실하지 않습니다.

2

글쎄, 엔티티 집합 만 얻을 수 있습니다. 기본 클래스 그래서 .AddToBaseEntity 같은 솔루션입니다.

그러나 모델에 순환 종속성이있는 것처럼 들리므로 Entity 프레임 워크는 저장할 순서를 알 수 없습니다.

파생 된 엔티티의 기본 항목에 외래 키가 있는지 확인하고 모델을 업데이트하십시오.

7

내 이름은 Phani이고 나는 ADO.NET Data Services 팀에서 일하고 있습니다.

ResolveNameResolveType 메서드는 클라이언트가 서버로 보낸 페이로드에 형식 정보를 사용자 지정하고 서버에서 응답 페이로드가 구체화되는 방식을 사용자 지정할 때 도움이됩니다. 그들은 당신이 클라이언트 유형을 해결하는 데 도움이 많은 시나리오에서 유용

은 몇 가지 예는 다음과 같습니다 기관의

  1. 유형 계층 구조는 서버에 비해 클라이언트에서 다르다.
  2. 서비스에 의해 노출 된 엔터티 형식은 상속에 참여하며 클라이언트에서 파생 된 형식으로 작업하려고합니다.

ResolveName은 서버에 요청할 때 연결 한 엔터티의 이름을 변경하는 데 사용됩니다.

이 데이터 모델을 고려 서버에서 서버에 변경 사항을 제출시 관리자 엔티티 유형, 의 인스턴스와 함께 작동하도록 클라이언트를 사용하는 경우, 우리가 존재하는 정보를 입력 기대

public class Employee { 
    public int EmployeeID {get;set;} 
    public string EmployeeName {get;set;} 
} 

public class Manager:Employee { 
    public List<int> employeesWhoReportToMe {get;set;} 
} 

엔티티가 상속에 참여할 때 페이로드에 저장됩니다. 클라이언트가이 페이로드를 직렬화 할 때

context.AddObject("Employees",ManagerInstance); <-- add manager instance to the employees set. 
context.SaveChanges(); 

그러나, 서버에 예상되는되지 어떤 형식 이름 으로 "직원"에 넣습니다. 은 그러므로 당신은

context.ResolveName = delegate(Type entityType){ 
    //do what you have to do to resolve the type to the right type of the entity on the server 
    return entityType.FullName; 
} 

타입의 해결 같은 방식으로 사용하는 경우, 클라이언트 이름 확인자을 제공해야합니다.

context.ResolveType = delegate(string entitySetName){ 
    //do what you have to do to convert the entitysetName to a type that the client understands 
    return Type.GetType(entitySetName); 
} 
1

이후 2 년 동안오고 있지만, 검색 트래픽이 관련 유지의 이익, 우리가 신속하게 준비 데이터에 대한 Wego의 데이터베이스를 채우는 데 사용했던 나는 신속 편리한 클래스에서이 문제를 해결 일한 방법 .

이전 버전은 확실하지 않지만 Entity Framework 4를 사용하면 개체를 컨텍스트에 기본 개체로 덤프 할 수 있으며 프레임 워크에서 서버 쪽 참조를 파악할 수 있습니다. 따라서 AddToInheritedObjects() (어쨌든 사용되지 않음) 대신 ObjectSet <> .Add() 메서드를 사용하게됩니다.쉽게 컨텍스트에 엔티티를 추가 할 수

class ObjectOne : BaseObject {} 
class ObjectTwo {} 

: 다음이 가정, 따라서

public ContextHelper 
{ 
     … 
     _context = ModelEntities(); 

     public T Create<T>() where T : class 
     { 
      // Create a new context 
      _context = new ModelEntities(); 

      // Create the object using the context (can create outside of context too, FYI) 
      T obj = _context.CreateObject<T>(); 

      // Somewhat kludgy workaround for determining if the object is 
      // inherited from the base object or not, and adding it to the context's 
      // object list appropriately.  
      if (obj is BaseObject) 
      { 
       _context.AddObject("BaseObjects", obj); 
      } 
      else 
      { 
       ObjectSet<T> set = _context.CreateObjectSet<T>(); 
       set.AddObject(obj); 
      } 

      return obj; 
     } 
     … 
} 

:

여기 헬퍼 클래스의 예입니다

ContextHelper ch = ContextHelper() 
ObjectOne inherited = ch.Create<ObjectOne>(); 
ObjectTwo toplevel = ch.Create<ObjectTwo>(); 
… 

기억하는, 물론 ContextHelper에는 _context.SaveChanges() - o를 호출하는 public Save() 메서드가 있어야합니다. r 개체 변경 사항을 데이터 저장소로 푸시하는 다른 방법이 있어야합니다.

이것은 상속에 관한 주어진 질문에 대한 직접적인 응답 일 수는 없지만 사람들에게 응답 세부 사항의 출발점을 제공 할 수 있기를 바랍니다.

+0

IDisposable을 구현하는 것을 잊어 버린 점은이 점이 정말 좋습니다. – JohnMetta

관련 문제