문제

기본 엔티티를 여러 가지 다른 것 (예 : 직원, 차량 등)으로 확장 해야하는 응용 프로그램을 작성하고 있습니다. 디자인은 엔티티 테이블과 유형 별 값이있는 두 번째 테이블이있는 것과 같습니다. (직원에게는 ID 번호가 있지만 차량에는 등록 번호가 있습니다.

데이터 컨텍스트에서 생성 된 클래스 엔티티에서 물려 받았지만 저장소의 캐스팅에 문제가 있습니다. 이 작업을 수행하는 올바른 방법은 무엇입니까?

public class cAccountEmployee : cAccountEntity
{
    public string id_number
    {
        get
        {
            try
            {
                return this.cAccountEntityValues.Single(e => e.type == 1).value;
            }
            catch (Exception)
            {
                return "";
            }
        }

        set
        {
            try
            {
                this.cAccountEntityValues.Single(e => e.type == 1).value = value;
            }
            catch (Exception)
            {
                this.cAccountEntityValues.Add(new cAccountEntityValue()
                                            {
                                                accountentity_id = this.id,
                                                cAccountEntity = this,
                                                type = 1,
                                                value = value
                                            });
            }
        }
    }

}

그런 다음 내 저장소에서 (아무것도 상속하지 않음)

public IEnumerable<cAccountEmployee> All(int accountholder_id)
    {
        return db.cAccountEntities.Where(e => e.accountholder_id == accountholder_id).OrderBy(a => a.name).Cast<cAccountEmployee>();
    }

    public cAccountEmployee Single(int id)
    {
        return db.cAccountEntities.Single(a => a.id == id) as cAccountEmployee;
    }

캐스트는 단일 방법으로 실패하므로 NULL이됩니다. 기본 클래스에서 또는 기본 클래스에서 명시 적 또는 암시 적 연산자를 정의 할 수 없다는 것은 내 이해입니까? 기본 클래스 LINQ 결과를 어떻게 상속 된 직원 클래스에 올리도록하고, 여전히 DB 상태를 유지하여 변경 사항을 제출할 수 있습니까?

도움이 되었습니까?

해결책

LINQ-to-SQL을 사용하면 상속이 작동 할 수있는 두 가지 방법이 있습니다.

  • 단일 테이블 위의 판별 자 (데이터가 동질하지 않기 때문에 적합하지 않음)
  • 기본 클래스 / 멀티 테이블 (DBML에서는 지원되지 않는 것이 아닙니다. 수업을 수동으로 작성하는 경우에만)

LINQ-to-SQL은 다중 테이블 상속을 지원하지 않습니다 (즉, 여러 테이블의 데이터가있는 단일 객체). 엔티티 프레임 워크는하지만 더 복잡합니다. 너는 사용한다 .Cast<T> 그리고 .OfType<T> 하위 유형을 기준으로 EF에서 캐스트/필터로

당신은 다음을보고 싶을 수도 있습니다.

여기서 기본 클래스의 목적은 무엇입니까? 동작이 추가되면 DBML을 편집하여 모든 엔티티에 공통 기본 클래스를 지정할 수 있습니다. 가지고 있다면 데이터 속성 그러면 까다로워집니다.

개인적으로, 나는 단순히 이런 식으로 그렇게하지 않을 것입니다 ... 나는 다른 유형에 대한 별도의 클래스를 유지하고 유형 당 별도의 테이블을 사용하여 데이터 컨텍스트를 올바르게 사용할 것입니다.

public IEnumerable<Employee> All(int accountholder_id)
{
    return db.Employees.Where(e => e.accountholder_id == accountholder_id)
        .OrderBy(a => a.name);
}

public Employee Single(int id)
{
    return db.Employees.Single(a => a.id == id);
}

그래서 - 당신은 무엇을 명확히 할 수 있습니까? cAccountEntity 여기에?

다른 팁

입력에 감사드립니다. 몇 가지 제안을 살펴 보겠습니다 ...

계정 엔티티의 아이디어는 현재 사이트가 직원 만 처리하면되지만 앞으로는 차량 등을 시스템에 추가하기를 원할 수도 있고 시스템은 엔터티에 비용을 할당하는 데 사용되므로 직원은 직원이 차량과 동일하게 처리했습니다.

아이디어는 직원과 차량이 DB 등을 참조하기 위해 동일하게 처리해야하지만 이에 대한 정보가 약간 다른 정보가 필요하다는 것입니다. 나중에 추가 유형을 추가하기를 원하지만 DB를 업그레이드 할 필요없이 복잡한 디자인입니다.

그러나 내 코드에서는 일반 엔티티 유형이 아닌 직원에 대해 이야기하고 싶습니다 (MVC 앱에서 컨트롤러,보기 등을 훨씬 쉽게보기). 기본에서 파생 클래스로 사용자 정의 캐스팅을 공급할 수 없으므로 물속을 건너 뛰고 다음 솔루션을 대신 사용했습니다. 조금 더 번거롭지 만 작동합니다 ... 누군가 더 나은 방법을 볼 수 있는지 알려주세요.

public class cAccountEmployee
{
    private cAccountEntity entity;

    public int id
    {
        get
        {
            return this.entity.id;
        }
        set
        {
            this.entity.id = value;
        }
    }

    public string name
    {
        get
        {
            return this.entity.name;
        }
        set
        {
            this.entity.name = value;
        }
    }

    public int accountholder_id
    {
        get
        {
            return this.entity.accountholder_id;
        }
        set
        {
            this.entity.accountholder_id = value;
        }
    }

    public System.Data.Linq.EntitySet<cAccountEntityValue> cAccountEntityValues
    {
        get
        {
            return this.entity.cAccountEntityValues;
        }
    }

    public cAccountHolder cAccountHolder
    {
        get
        {
            return this.entity.cAccountHolder;
        }
    }

    public cAccountEmployee()
    {
        this.entity = new cAccountEntity();
    }

    public cAccountEmployee(cAccountEntity entity)
    {
        this.entity = entity;
    }

    public string id_number
    {
        get
        {
            try
            {
                return this.entity.cAccountEntityValues.Single(e => e.type == 1).value;
            }
            catch (Exception)
            {
                return "";
            }
        }

        set
        {
            try
            {
                this.entity.cAccountEntityValues.Single(e => e.type == 1).value = value;
            }
            catch (Exception)
            {
                this.entity.cAccountEntityValues.Add(new cAccountEntityValue()
                                            {
                                                accountentity_id = this.id,
                                                cAccountEntity = this.entity,
                                                type = 1,
                                                value = value
                                            });
            }
        }
    }
}

//In the repository
public cAccountEmployee Single(int id)
    {
        return new cAccountEmployee(db.cAccountEntities.Single(a => a.id == id));
    }

기본 클래스 LINQ 결과를 상속받은 직원 클래스에 올리도록하려면 어떻게해야합니까?

그것은 업 캐스트가 아니라 다운 캐스트입니다.

캐스팅이나 인스턴스 유형 대 참조 유형을 이해하지 못한다고 생각합니다.

public class Animal { }
public class Zebra : Animal { }

public class Zoo
{
    public void ShowZebraCast()
    {
        Animal a = new Animal();
        Zebra z = (Zebra)a;
    }
}

System.InvalidCastException : '동물'유형의 대상을 캐스트 할 수 없습니다.

같은 방식으로, 당신은 직원 참조를 사용하기 위해 다운 캐스트 할 수없는 엔티티 인스턴스가 있습니다.

유형을 변환 할 수 있지만 변환 방법을 제공해야합니다.

public partial class Animal { }
public class Zebra : Animal { }
//in another file
public partial class Animal{
  public Zebra ToZebra(){
    return new Zebra() { //set Zebra properties here.
    };
  }
}


public class Zoo
{
    public void ShowZebraConvert()
    {
        Animal a = new Animal();
        Zebra z = a.ToZebra();
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top