2016-03-03 11 views
6

異なるIDタイプの可能性があるタイプに対応する一般的なGetById(T id)メソッドを実装しようとしています。私の例では、IDがint、タイプがstringのエンティティを持っています。一般的なGetById()の実装方法IDはさまざまな種類があります。

しかし、私はエラーを取得しておくと、私はその理由は考えていません:

型「intは」メソッドIEntityのジェネリック型のパラメータ「TID」としてそれを使用するために、参照型でなければなりませんが

エンティティインタフェース:

タイプintまたはstringのIDを持つことができ、私のドメインモデルに対応するために。

public interface IEntity<TId> where TId : class 
{ 
    TId Id { get; set; } 
} 

エンティティの実装:

public class EntityOne : IEntity<int> 
{ 
    public int Id { get; set; } 

    // Other model properties... 
} 

public class EntityTwo : IEntity<string> 
{ 
    public string Id { get; set; } 

    // Other model properties... 
} 

ジェネリックリポジトリインタフェース:

public interface IRepository<TEntity, TId> where TEntity : class, IEntity<TId> 
{ 
    TEntity GetById(TId id); 
} 

一般的なリポジトリの実装:

public abstract class Repository<TEntity, TId> : IRepository<TEntity, TId> 
    where TEntity : class, IEntity<TId> 
    where TId : class 
{ 
    // Context setup... 

    public virtual TEntity GetById(TId id) 
    { 
     return context.Set<TEntity>().SingleOrDefault(x => x.Id == id); 
    } 
} 

リポジトリの実装:

public class EntityOneRepository : Repository<EntityOne, int> 
    { 
     // Initialise... 
    } 

    public class EntityTwoRepository : Repository<EntityTwo, string> 
    { 
     // Initialise... 
    } 
+6

からcontraintを削除しますか?これは 'int'では機能しません(エラーメッセージはそれをかなり明確にします)。 'class'は、ジェネリック制約の「参照型」を意味します。 –

答えて

2

あなたは、あなたの質問にあなたのRepositoryクラス

public abstract class Repository<TEntity, TId> : IRepository<TEntity, TId> 
where TEntity : class, IEntity<TId> 
{ 
    public virtual TEntity GetById(TId id) 
    { 
     return context.Set<TEntity>().Find(id); 
    } 
} 
+0

この提案は、参照型のエラーを解決しますが、IDで一致を実行しようとすると、演算子==はTId型とTId型のオペランドには適用できません。 – Tomuke

+0

' .SingleOrDefault(x => x.Id == id) 'の代わりに.Find(id)'を使用します。私はそれがこのメソッドの背後にまったく同じことをしていると思うので、 '.Find()'がなぜ有効であるのかは分かりません。 – Tomuke

+0

それは私のために働いていない。 .SingleOrDefault(x => x.Id == id) ''エラーに対してエラー –

1

からTID上の制約を削除する必要があります。
私はジェネリックを実装しようとしていますGetById(T id)メソッドは、異なるIDタイプを持つ可能性のある型を処理します。私の例では、型intのIDと型stringのエンティティを持っています。一般的なパラメータについては

public virtual TEntity GetById<TId>(TId id) 
    { 
     return context.Set<TEntity>().SingleOrDefault(x => x.Id == id); 
    } 

、ちょうど

2
public interface IEntity<TId> where TId : class 
{ 
    TId Id { get; set; } 
} 

上記のような一般的な方法を作るwhere TId : class制約は、int型のような値型のために真ではないオブジェクトから派生したIDを持つために、すべての実装が必要です。エラーメッセージがあなたに伝え何ザッツ

:あなたはclass`タイプ `に` TId`を制限しているのはなぜThe type 'int' must be a reference type in order to use it as parameter 'TId' in the generic type of method IEntity

ちょうどIEntity<TId>

関連する問題