次のインターフェースを定義しています。
IDbContext
public interface IDbContext<T> : IDisposable where T : class
{
DbSet<T> Set<T>();
int SaveChanges();
}
これは TestContext によって間接的に実装されます。TestContext は System.Data.Entity.DbContext から派生していることに注意してください。
public class TestContext: DbContext,IDbContext<Foo>
{
}
Foo は何らかのエンティティです
public class Foo
{
public int Id { get; set; }
public string Name { get; set; }
}
コンパイラは次のエラーをスローします。
型 'T' は、ジェネリック型またはメソッド 'System.Data.Entity.DbSet' TestContext.cs でパラメーター 'TEntity' として使用するには、参照型である必要があります。
型 'T' は、ジェネリック型またはメソッド 'System.Data.Entity.DbSet' IDbContext.cs でパラメーター 'TEntity' として使用するには、参照型である必要があります。
メソッド 'System.Data.Entity.DbContext.Set()' の型パラメーター 'TEntity' の制約は、インターフェイス メソッド 'Domain.Logic.Repositories.IDbContext.Set()' の型パラメーター 'T' の制約と一致する必要があります。代わりに、明示的なインターフェイスの実装を使用することを検討してください。
EntityFramework.dll
IDbContext インターフェイスの Generic メソッドに制約を追加すると、エラーはなくなります。
public interface IDbContext<T> : IDisposable where T : class
{
DbSet<T> Set<T>() where T : class;
int SaveChanges();
}
メソッドがクラスレベルで定義されているときに、メソッドの制約を明示的に定義する必要があるのはなぜですか?
更新 コメントに基づいて、自分が犯した間違いに気づきました。
DbContext.Set() メソッドの型パラメーターを完全に見落としていました。ジェネリック メソッドの型パラメーターは、そのクラス/インターフェイスの型パラメーター (存在する場合) とは異なるため、別の名前を付ける必要があります。私の場合、いくつかの問題がありました。1) 同じパラメーター名を持つジェネリック型メソッドを持つジェネリック インターフェイスがありました。2) ジェネリック型付きメソッド自体は、独自の制約を持つ DbContext.Set() をモデルに作成されましたが、これらの制約はジェネリック メソッド自体には適用されませんでした。
以下の回答で提供されているように、オプション3を使用しました。
public interface IDbContext : IDisposable {
DbSet<T> Set<T>() where T : class
int SaveChanges();
}
HTH