0

DbSets ではなく、データベースから IQueryables にアクセスできるマルチテナンシーを実装しているため、Add、Remove、Find のジェネリックを実装しています。

Add の実装方法:

前のコード:

interest = db.Interests.Add(new Interest()) // Interests is dbSet

後のコード:

interest = db.Add(new Interest()) // Interests is dbSet

// in db class
public T Add<T>(T item) where T : class, ITenantData
    {
        var set = _appContext.Set<T>();
            return set.Add(item);
    }

これは機能します。今、私は Find に対して同じことをしようとしていますが、Typed パラメーターではなく Id を使用しているため、少し行き詰まっています。

前のコード:

var aptitude = db.Aptitudes.Find(interest.AptitudeId);  // Aptitudes is a DbSet

後のコード:

var aptitude = db.Find(interest.AptitudeId); // how to identify type?

私はこれを行うことはできません:

var aptitude = db.Aptitudes.Find(interest.AptitudeId);

Aptitudes が IQueryable になったためです。

したがって、これは現在失敗しています:

public T Find<T>(T query) where T : class, ITenantData
    {
        var set = _mentorContext.Set<T>();
        return set.Find(query);
    }

タイプが識別されていないため、次のようになります。

型 'int' は、ジェネリック型またはメソッド 'App.Context.TenantContext.Find(T)' Service.cs でパラメーター 'T' として使用するために、参照型である必要があります。

私はジェネリックに少し慣れていません。ここで何か助けていただければ幸いです。

4

1 に答える 1

1

これを拡張メソッドで解決します。

public IQueryable<T> Query<T>() where T : class, ITenantData
{
    return _mentorContext.Set<T>().AsNoTracking();
}

...その間、別のクラスで...

public static MentorContextExtensions
{
    public static InterestEntity ByAptitudeId(
        this IQueryable<InterestEntity> queryable, 
        int aptitudeId)
    {
        return queryable.SingleOrDefault(x => x.AptitudeId == aptitudeId);
    }
}

...に対する使用IQueryable<T>...

db.Query<InterestEntity>().ByAptitudeId(interest.AptitudeId);

上記の例は を返しますが、 、を使用する などを使用して、セット (事前にフィルター処理されたまたは) をSingleOrDefault簡単に返すこともできます。IQueryablesIEnumerables.Wherebool.Any

.Findで(主キーによる) メソッドの使用を維持するには、次のIDbSetようにします。

public T Find<T>(params object[] keyComponents) where T : class, ITenantData
{
    return _mentorContext.Set<T>().Find(keyComponents);
}

...そして、このように使用します...

var aptitude = db.Find<Aptitude>(interest.AptitudeId);

...とは言う.Findものの、ある種のミューテーションコードで、エンティティで挿入、更新、削除を行っている場合にのみ、使用が高速になる可能性があります。.Find常にエンティティをコンテキストにアタッチしたままにします。これは、データを変更する必要がある場合に必要です。.AsNoTracking()ただし、単一のエンティティを返すため、呼び出すことはできません。エンティティがそのプロパティを読み取るため、または表示目的でのみ必要な場合、.AsNoTrackingはエンティティ グラフ全体 (エンティティとそのナビゲーション/コレクション プロパティ) をコンテキストから分離したままにします。これは、 を使用するよりも高速な場合があります.Find。後でミューテーション コードで同じエンティティ インスタンスを使用する場合は、その時点でコンテキストにアタッチできます。

于 2013-11-04T18:17:42.047 に答える