2016-04-17 9 views
1

汎用基本クラスを持つ汎用リポジトリを作成しようとしています。汎用汎用キーフィールドを持つ基本クラスを使用したC#の追加/付加

Fo rmyベースクラスです。私はそれによってT.Idがデフォルトの状態にあるかどうかに基づいて、追加または削除のいずれかの一般的なリポジトリへの拡張メソッドを追加するインターフェイス

public interface IEntity<T> 
{ 
    T Id { get; set; } 
    bool? Archived { get; set; } 
} 

public abstract class Entity<T> : IEntity<T> 
{ 
    public abstract T Id { get; set; } 

    [Column("IsArchived")] 
    public bool? Archived { get; set; } 
} 

ない。私の方法は以下の通りです。

public static TContext Attach<T, TKey, TContext>(this TContext context, T entity) 
     where T : class, IEntity<TKey> 
     where TContext : BaseDataContext 
    { 
     if (EqualityComparer<T>.Default.Equals(entity.Id, default(TKey))) 
     { 
      context.Set<T>().Add(entity); 
     } 
     else 
     { 
      context.Entry(entity).State = EntityState.Modified; 
     } 
     return context; 
    } 

私はその後、私は一般的な方法「Repository.Extensions.Attachを使用して、エラー

エラー9を得る

public async Task<Entity<T>> SaveAsync<T, TKey>(Entity<T> entity, string userName) where T : class, IEntity<TKey> 
    { 
     this.Attach(entity); 
     await this.SaveChangesAsync(); 
     return entity; 
    } 

すなわちリポジトリから拡張メソッドを呼び出したいコール(TContext 、T) 'は3つの型引数を必要とします

これは、基本クラスがジェネリック型、つまりint型でない場合にうまくいきます。これを修正するには何を調整する必要がありますか?

+0

何もあなたはありません調整することができます。コンパイラは 'TKey'引数を派生させることはできません。残念なことにこのような場合は、すべてのジェネリック型引数を指定する必要があります。 –

答えて

1

コメントで述べたように、このデザインでは何もできません。コンパイラはの引数をentityの引数のTの引数contextから推測しますが、TKeyの推論に使用できる引数はありません。 TIEntity<int>,IEntity<string>などを同時に実装することがありますので、技術的には使用している具体的なクラスからそれを導き出せるはずですが、現時点ではそうではありません。

この問題を回避するには、このような非ジェネリックインターフェイスを定義することによってTKeyを排除することができます

モデル:

public interface IEntity 
{ 
    bool? Archived { get; set; } 
    bool IsNew { get; } 
} 

public interface IEntity<T> : IEntity 
{ 
    T Id { get; set; } 
} 

public abstract class Entity<T> : IEntity<T> 
{ 
    public abstract T Id { get; set; } 

    [Column("IsArchived")] 
    public bool? Archived { get; set; } 

    public virtual bool IsNew { get { return EqualityComparer<T>.Default.Equals(Id, default(T)); } } 
} 

拡張方法:

public static TContext Attach<T, TContext>(this TContext context, T entity) 
     where T : class, IEntity 
     where TContext : DbContext 
{ 
    if (entity.IsNew) 
    { 
     context.Set<T>().Add(entity); 
    } 
    else 
    { 
     context.Entry(entity).State = EntityState.Modified; 
    } 
    return context; 
} 
+0

ご清聴ありがとうございます。 –

関連する問題