2012-01-09 3 views
2

다음 코드를 고려 실제로 삭제하는 대신 삭제됩니다.C#을 추상 클래스 일반적인 특성은

public virtual void Delete(T entity) 
    { 
     entity.Deleted = true; 
     dbset.Attach(entity); 
     dataContext.Entry(entity).State = EntityState.Modified; 
    } 

나는 POCO 엔티티를 사용하고 있으며 모두 삭제 된 속성이 있습니다. 그러나 위 코드에서 entity는 T 유형이고 T는 표현할 수있는 모든 객체에 Deleted 속성이 있다는 것을 "알지 못합니다." 이것을 해결하는 가장 우아한 방법은 무엇입니까?

그건 그렇고, 내 추상 클래스에서 비슷한 방식으로 다른 필드 (DateCreated, CreatedBy, DateModified 및 ModifiedBy)에 액세스하고 싶습니다.

UPDATE : 나는 인터페이스와 처음에는 좋은 듯 추상 클래스 솔루션을 모두 시도했지만 컴파일 할 때 나는 두 경우 모두 다음과 같은 오류 메시지를 받았습니다 :

에러 11 종류를 ' MyProject.Domain.Person '은 제네릭 형식 또는 메서드'MyProject.Data.Infrastructure.RepositoryBase '에서 형식 매개 변수'T '로 사용할 수 없습니다. 'MyProject.Domain.Person'에서 'MyProject.Domain.AbstractEntity'로의 암시적인 참조 변환은 없습니다.

namespace MyProject.Data 
{ 
    public class PersonRepository : RepositoryBase<Person>, IPersonRepository 
    { 
     public PersonRepository(IDatabaseFactory databaseFactory) 
      : base(databaseFactory) 
     { 
     } 
    } 

    public interface IPersonRepository : IRepository<Person> 
    { 

    } 
} 

업데이트 2 : 나는 마침내 그것을 가지고

가 SLaks에 의해 제안 된 솔루션과 함께 작동하도록 여기

그리고

오류 메시지가 참조하는 코드입니다. 나는 인터페이스를 사용하고, 그들은 모두 다음과 같은 IEntity 인터페이스에서 파생 할 수 있도록 나는 모든 POCO 엔티티를 생성하는 템플릿을 수정 :

namespace MyProject.Domain 
{ 
    public interface IEntity 
    { 
     System.DateTime CreatedDate 
     { 
      get; 
      set; 
     } 

     string CreatedBy 
     { 
      get; 
      set; 
     } 

     System.DateTime ModifiedDate 
     { 
      get; 
      set; 
     } 

     string ModifiedBy 
     { 
      get; 
      set; 
     } 

     bool Deleted 
     { 
      get; 
      set; 
     } 
    } 
} 

더 복잡한 것 추상 엔티티 클래스를 사용의 모든 속성이 있기 때문에, 추상 클래스는 엔티티 클래스에서 오버라이드되어야합니다.

+0

이 당신에 대해 요구하는'여기서 T : 클래스, MyClass'? – Tigran

+0

@ Tigran 나는 그것을 시도했지만 컴파일 오류 메시지가 나타납니다. 위의 업데이트를 참조하십시오. –

+0

컴파일러 오류는 Person이 AbstractEntity에서 상속하지 않는다는 것을 의미합니다. 기본 클래스를 재정의하는 것을 잊었습니까? – phoog

답변

3

당신은 Deleted와 다른 특성을 가진 인터페이스를 생성해야하고 엔티티 클래스에 구현합니다.
그런 다음 인터페이스를 구현하기 위해 제네릭 형식 매개 변수를 제한 할 수 있습니다.

+0

이것에 대해 생각했지만 간단한 솔루션을 원했습니다. POCO 엔티티가 T4 템플릿으로 자동 생성되기 때문입니다. 물론 템플릿을 수정할 수는 있지만 T4 템플릿은 나에게 새롭고이 수정 작업을 얼마나 빨리 수행 할 수 있는지 잘 모르겠습니다. –

+0

T4를 수정하지 않고 다른 클래스의 부분 클래스에 인터페이스를 구현할 수 있습니다 (이미 존재하지 않는다면'partial' 키워드를 추가하는 것을 제외하고) – SLaks

+0

당신은 이미 템플릿을 수정하여 "부분적인" 키워드, 그래서 모든 엔티티 IEntity (당신이 추가 할 제안 된 인터페이스)에서 파생 될 수 있도록 서식 파일을 수정하는 것이 어렵지 않아야한다고 생각했는데, 이제 모든 것이 잘 컴파일됩니다. 감사! –

5

는 인터페이스 (의 말 IDeleteable을하자)로 삭제 된 속성을 넣고 일반적인 제약 조건 클래스를 제한 :

public interface IDeleteable { Boolean Deleted { get; set; } } 

public abstract class RepositoryBase<T> where T : class, IDeleteable 

편집 :이 암시라고 생각했다, 그러나 당신은에 인터페이스를 구현해야 엔티티 클래스

public class Person : IDeleteable { ... } 
+0

@Chris_Shain 귀하의 솔루션을 시도했지만 컴파일 시간에 오류가 발생했습니다. 내 오류를 보려면 위의 내 업데이트를 참조하십시오. –

+0

모든 엔티티 클래스의 인터페이스를 실제로 구현해야합니다. ... –

+0

@Chris_Shain 감사합니다. 나는 마침내 그 작업을 수행했으며 현재 작동 중입니다. 그는 솔루션을 먼저 제안했기 때문에 SLaks에 대한 올바른 답을 주었지만 예제에서 코드를 작성하는 데 +1을주었습니다. 감사! –

3

당신은 AbstractEntity는 당신이 필요로하는 모든 특성을 것

// from 
public abstract class RepositoryBase<T> where T : class 

// to 
public abstract class RepositoryBase<T> where T : AbstractEntity 

제약

에 대한 추상 클래스를 사용할 수 있습니다. 인터페이스와 달리 추상 클래스는 기본 구현을 제공 할 수 있습니다.

+0

+1 추상 기본 클래스의 사용을 정당화하기 위해 +1. –

+0

@oleksii :이 솔루션을 시도해 보았지만 좋았지 만 컴파일 할 때 또 다른 문제가 발생했습니다. 특정 오류 메시지는 위의 업데이트를 참조하십시오. –

1

다른 사람들은 인터페이스 또는 추상 클래스를 사용하여 언급했습니다. 이것은 전심으로 권하는 것입니다. 어떤 바보 같은 이유로, 가능하지 않은 경우, 당신은 또한 반사를 사용할 수 있습니다

entity.Deleted = true; 

은 대체 될 것이다 :

var type = typeof(T); 
var property = type.GetProperty("Deleted"); 
property.SetValue(entity, true, null);