4

私の素朴さを前もってお詫び申し上げます。

ドメイン モデルで定義したエンティティを永続化するために Entity Framework を使用しています。私のドメイン モデル エンティティはすべて、私の EntityBase クラスから継承しています。これには、すべてのエンティティに共通にしたいプロパティがあります。

public class EntityBase
{
    public string CreatedBy { get; set; }
    public DateTime? Created { get; set; }

    public int ModifiedBy { get; set; }
    public DateTime? Modified { get; set; }

    public bool Enabled { get; set; }
    public bool Deleted { get; set; }
}

LINQ を使用して EF にクエリを実行する場合、特定のエンティティが有効になっているか削除されているかを確認するために要素を含める必要がなければいいと思います。すべてのクエリには、次のようなコードが含まれます。

var messages = _db.Memberships.Where(m => m.UserId.Equals(userId))
                              .SelectMany(m => m.Group.Messages)
                              .Include(m => m.Group.Category)
                              .Select(m => m.Enabled && !m.Deleted) 
                              .ToList();

毎回これを行うのではなく、IQueryable で動作する拡張メソッドを作成することにしました。

public static IQueryable<EntityBase> Active(this IQueryable<EntityBase> entityCollection)
    {
        return entityCollection.Where(e => e.Enabled && !e.Deleted);
    }

私の素朴さで、EntityBaseクラスから継承するエンティティを返すLINQクエリにこれを含めることができると考えました-次のように:

var messages = _db.Memberships.Where(m => m.UserId.Equals(userId))
            .SelectMany(m => m.Group.Messages)
            .Include(m => m.Group.Category)
            .Active() <============================= Extension Methd
            .ToList();

        return Mapper.Map<List<Message>,List<MessageDto>>(messages);

ただし、コンパイラは次のように不平を言います。

Error 2 Argument 1: cannot convert from
          'System.Collections.Generic.List<Diffusr.Business.Entities.EntityBase>' to
          'System.Collections.Generic.List<Diffusr.Business.Entities.Message>'  

質問: 達成したいこと、つまり、すべてのエンティティが Enabled のみを返し、Deleted を返さない共通の方法を達成できますか? もしそうなら、どのように?

4

2 に答える 2

4

ほとんどの拡張メソッドが行うように、具体的なクラスを指定する代わりに、ジェネリックを使用します。

public static IQueryable<T> Active<T>(this IQueryable<T> entityCollection) where T:EntityBase
{
    return entityCollection.Where(e => e.Enabled && !e.Deleted);
}

4.0 より前のバージョンの .NET を使用していると思います。ジェネリック共分散は 4.0 より前では許可されていませんでした (つまり、基本型の列挙型が予期される場合に、子型の列挙型を渡します)。

4.0 以降でも、リストに新しい値を格納しようとするたびに、型の安全性を確保するためにコンパイラが多くの追加チェックを行うことになるため、共分散を使用することは絶対に最善の方法ではありません。Jon Skeet には、これに関する素晴らしい記事があります。

于 2013-10-10T12:27:30.200 に答える
3

拡張メソッドを変更することで、次のことができます。

public static IQueryable<T> Active(this IQueryable<T> entityCollection)
    where T : EntityBase
{
    return entityCollection.Where(e => e.Enabled && !e.Deleted);
}
于 2013-10-10T12:27:22.727 に答える