2

Repository patternメンバーが実装されるユニバーサル基本クラスを作成しようとしています。コードは次のとおりです。

public abstract class RepositoryBase<TEntity, TType> : IRepository<TEntity, TType>
    where TEntity : EntityBase<TType>
{
    public IAdNetMsSqlContext Context { get; set; }
    public DbSet<TEntity> DbSet { get; set; }

    public RepositoryBase(IAdNetMsSqlContext context)
    {
        Context = context;
        DbSet = context.Set<TEntity>();
    }

    public IQueryable<TEntity> Get(TType id)
    {
        //!!! Here is an error
        return DbSet.FirstOrDefault(e => e.Id == id);
    }
    ....
}

そして、私はエラーが発生します:

   Error    1   Operator '==' cannot be applied to operands of type 'TType' and    `'TType' .... AdNet.Common.Base

行で:

   return DbSet.FirstOrDefault(e => e.Id == id);

何を考えたらいいのかわからない。TType は確実に TType と同じです。

どんな前進でもThx!

4

3 に答える 3

7

ここには 2 つの問題があります。

  • IQueryable<TEntity>whenを返そうとしているFirstOrDefaultのは単一の のみを返すTEntityため、戻り値の型を変更する必要があります
  • ==制約のないジェネリックでは許可されていないものを使用しようとしています。クラスになるように制約TTypeすることもできますが、その時点で参照の等価性が実行されますが、与えられた例を考えると、おそらくそれは望ましくありません。

とにかくこれがSQLに変換されることを考えると(したがって、ボクシングの影響を心配する必要はありません)、使用するように変換するだけEqualsです:

public TEntity Get(TType id)
{
    return DbSet.FirstOrDefault(e => e.Id.Equals(id));
}

それともそもそも使えないDbSet<TEntity>.Findの?

public TEntity Get(TType id)
{
    return DbSet.Find(id);
}
于 2013-03-28T11:59:02.443 に答える
1

TTypeが明らかに等しいことはわかっているかもしれませんがTType、コンパイラが知らないのは、任意の制約のない演算子 (別名)TTypeがあるかどうかです。==op_Equality

代わりに使えますEqualsか?

return DbSet.FirstOrDefault(e => e.Id.Equals(id));
于 2013-03-28T12:01:09.160 に答える
0

たまたま、両方のジェネリックが同じ名前を共有しています: TType

コンパイラの観点からは、e.Id が id と同じであることを認識していないため、シナリオを真にするコードを記述できる可能性が高くなります。

TType の比較では、それが物理的に同じオブジェクトであり、同じ値を持つ 2 つのオブジェクトではないことが確認されると想定しています。両方を Object にキャストすると、比較が機能するはずです

于 2013-03-28T12:01:06.230 に答える