1

次のインターフェースを定義しています。

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

4

1 に答える 1

6

<T>inを削除するSet<T>DbSet<T> Set<T>() T別の名前を付けれSet<T>ば問題ありません。それ以外の場合は、 のパラメーターTとは異なるを定義しています。そのため、コンパイラは 2 番目の制約を必要とします。それは異なる. したがって、次の 2 つのオプションのいずれかが必要です。初め:TIDbContext<T>T

public interface IDbContext<T> : IDisposable where T : class {
    DbSet<T> Set();
    int SaveChanges();
}

また

public interface IDbContext<T> : IDisposable where T : class {
    DbSet<TEntity> Set<TEntity>() where TEntity : class;
    int SaveChanges();
}

または、ジェネリック パラメータを から削除しますIDbContext

public interface IDbContext : IDisposable {
    DbSet<T> Set<T>() where T : class
    int SaveChanges();
}

あなたのコメントに基づいて、後者はあなたのニーズにより適しているようです。

于 2013-06-19T01:20:55.620 に答える