2017-05-03 11 views
9

PersonBusiness.GetQueryのメソッドでは、PersonEntityがコード全体にわたっています。このメソッドを同様に実装する多くのエンティティタイプがあります。エンティティでのジェネリックの使用

PersonBusinessでジェネリックパラメータを使用して、特定のエンティティタイプの使用を減らしたいのですが、このような実装が他のエンティティと一緒にあり、意図したエンティティタイプの代わりに他のタイプを使用しないようにしたいからです。しかし、ジェネリックパラメータを使用したバージョンでは、成功または満足できませんでした。

さらに意味のある具体的なクラスではなく、インターフェイスを使用したいと思います。

+1

あなたは何の問題がありますか? – mclark1129

+0

IQueryable とIQueryable の間のコンパイルと互換性はありません。キャスティングはそれを解決しますが、その場合は多くのキャストがありますので匂いがします。私はそれが異なって設計されるべきだと思う。 – lockedscope

+0

あなたの投稿のタイトルはGenericです。 – niksofteng

答えて

5

ポストに私のコメントにもかかわらず、私は私がコンパイルここまで答えを置くはずと考えました。私がユースケースを理解していないので、適切な解決策を考えるのは難しいです。ここでは決して-レス@Ivan Stoevからのコメントあたりのキャストの賛成でDbSetを使用するように更新されたコード

public class PersonBusiness<T> : BaseBusiness<T> where T: PersonEntity 
{ 
    public IQueryable<T> GetQuery(string orderBy, int? groupId) 
    { 
     IQueryable<T> query = Db.Set<T>(); 

     Func<IQueryable<T>, IQueryable<T>> defaultOrderBy = null; 
     if (groupId.HasValue) 
     { 
      query = query.Where(d => d.Id == groupId); 
     } 
     else 
     { 
      defaultOrderBy = q => q.OrderBy(d => d.Id).ThenBy(d => d.FullName); 
     } 
     return GetQuery(query, orderBy, defaultOrderBy); 
    } 
    public override IQueryable<T> ApplyDefaultOrderyBy(IQueryable<T> query) 
    { 
     return query.OrderBy(q => q.FullName); 
    } 
} 

、です。

+1

@lockedscopeあなたのコメントに*タイプ推論*という言葉を数回使用しています。しかし、この用語はジェネリックメソッドに適用されますが、ここではジェネリッククラスに含まれます。したがって、すべてのメソッドは、あなたが**呼び出すことさえ可能にする前に解決する**タイプ**に関連付けられています。意図した使い方は 'var pb = new PersonBusiness ();のようなものです。 pb.GetQuery(...) '。だからあなたのデザインに関係する型推論はありません。どのような制約がありますか?** **では 'T'の' Id'と 'FullName'プロパティにアクセスできます。インタフェースクラスとベースクラスの両方が動作します。 –

+1

ジェフリーのコードは間違いなくコンパイルされています(それはあなたの後にあるものであれば別の話ですが、あなたの質問からはかなり不明です)。私が提案する唯一の変更は 'Db.PersonSet.Cast ()'の代わりに 'DbSet ()'を使うことです。 –

+0

申し訳ありませんが、私は物事が混ざり合って、実際にコンパイルします。 – lockedscope

0

私はPersonEntityをインターフェイスに引き出し、タイプ制約を使用してTがIPersonEntityを実装することを要求しました。私はあなたがしていることのポイントを見ていませんが、タイプ制約を使用したいと思っているだけで、それまでに聞いたことがないようです。

https://msdn.microsoft.com/en-us/library/d5x73970.aspx

public interface IPersonEntity 
{ 
    int Id { get; set; } 
    string FullName { get; set; } 
} 
public class PersonBusiness<T> where T : IPersonEntity 
{ 
    public IQueryable<T> GetQuery(string orderBy, int? groupId) 
    { 
     IQueryable<T> query = Db.PersonSet; 
     Func<IQueryable<T>, IQueryable<T>> defaultOrderBy = null; 
     if (groupId.HasValue) 
     { 
      query = query.Where(d => d.Id == groupId); 
     } 
     else 
     { 
      defaultOrderBy = q => q.OrderBy(d => d.Id).ThenBy(d => d.FullName); 
     } 
     return GetQuery(query, orderBy, defaultOrderBy); 
    } 
    public IQueryable<T> ApplyDefaultOrderyBy(IQueryable<T> query) 
    { 
     return query.OrderBy(q => q.FullName); 
    } 
    public IQueryable<T> GetQuery(IQueryable<T> query, string orderBy, Func<IQueryable<T>, IQueryable<T>> defaultOrderBy = null) 
    { 
     if (orderBy != null) 
      query = query.OrderBy(orderBy); 
     else 
      query = defaultOrderBy != null ? defaultOrderBy(query) : ApplyDefaultOrderyBy(query); 
     return query; 
    } 
} 
+0

型の推論に制約が使用されていないため、コンパイルされません – lockedscope

+0

実際にコードをコンパイルしようとしませんでした。型推論を使用しないときに機能しますか? – user2023861

+0

コンパイルされません。 – lockedscope

0

Daiコメント。このアプローチは、リポジトリパターンを破壊します。私のソリューションは、ジュリー・ラーマンは、このスニペットは助けることができるef-code-first-you-on-repository

ef architecture

パターンの実装とポストがある中で説明したとおりに一般的なリポジトリを作成することです。

public abstract class BaseRepository<T> : IBaseRepository<T> where T : class 
{ 
     public DbContext Context { get; protected set; } 

     public BaseRepository() 
     { 
      this.Context = new AppDbContext(); 
     } 

     public BaseRepository(AppDbContext context) 
     { 
      this.Context = context; 
     } 

     public IQueryable<T> AllIncluding(params Expression<Func<T, object>>[] includeProperties) 
     { 
      var query = Context.Set<T>().AsQueryable(); 
      foreach (var includeProperty in includeProperties) 
      { 
       query = query.Include(includeProperty); 
      } 

      return query; 
     } 

     public DbEntityEntry<T> Entry(T entity) 
     { 
      return this.Context.Entry(entity); 
     } 

     public virtual void InsertOrUpdate(params T[] entities) 
     { 
      foreach (var entity in entities) 
      { 
       this.Context.Entry(entity).State = EntityState.Added; 
      } 
     } 

     public void SaveChanges() 
     { 
      this.Context.SetCurrentStateToEntities(); 
      this.Context.SaveChanges(); 

      this.Context.SetToUndefined(); 
     } 
    } 
関連する問題