SQLデータベースのテーブルを更新するEntityFrameworkに基づいた関数を作成したいと思います。
このテーブルには親子関係があるため、に基づいて多数の子を更新していparentID
ます。
ジェネリック関数が欲しいのですが、コンパイル時に定義がわからないオブジェクトからIDを取得する方法がわかりません。
Func
かなりきれいなものを使用しようとしましたが、Linq-To-Entitiesでは使用できません。
コード:
protected static void update<TEntity>(DbSet<TEntity> set, int parentID,
List<TEntity> entities, Func<TEntity, bool> isNew, Func<TEntity, int> getID = null,
Func<TEntity, int> getParentID, Action<TEntity, TEntity> updateSingleEntity)
where TEntity : class
{
var currentIDs = entities.Select(e => getID(e));
var newEntities = entities.Where(e => isNew(e));
var existingEntities = entities.Where(e => !isNew(e));
var deletedEntities
= set.Where(e => getParentID(e) == parentID && !currentIDs.Contains(getID(e)));
foreach (var toAdd in newEntities)
{
set.Add(toAdd);
}
foreach (var toDelete in deletedEntities)
{
var entity = set.Find(getID(toDelete));
set.Remove(entity);
}
foreach (var toUpdate in existingEntities)
{
var entity = set.Find(getID(toUpdate));
updateSingleEntity(toUpdate, entity);
}
}
この関数を次のように使用したいと思います。
update(set, parentID, someList, e => e.ID != 0, e => e.ID, e => ParentID, somefunc);
それはかなりきちんとしたIMOです。このような関数を実装する方法はありますか?
できない(試した):
IDプロパティを持つインターフェイスはすっきりすることができます。ただしparentID
、このプロパティの名前はDB内のエンティティによって異なるため、このインターフェイスで定義することはできません。
まず、コメントで言われているように、を使用する必要がありますExpression<Func<TEntity,int>> getId
。
それを使用するには、これを行うのではなくentities.Select(e => getID(e))
、単にこれを行いentities.Select(getID)
ます。その理由はSelect
、ランバ式が必要でありgetId
、ラムダ式が含まれているためです。Expression<>
それは表現の仕事にEFのために必要な木ではなく、コンパイル済みの表現ですので、必要です。詳細については、これを読むことができます。
インターフェイスの代替ソリューションについては、次のように実装する必要があります。
public interface IId
{
public int GetId();
}
次に、たとえば次のように、すべてのクラスに実装する必要があります。
public int GetId() { return parentId; }
または
public int GetId() { return parentId; }
また、次のように一般的なメソッドにインターフェイス制約を追加する必要があります。 where TEntity: class ,IId
ただし、2つの問題があります。
GetId
すべてのエンティティタイプ(または少なくともこのメソッドで使用されるエンティティタイプ)に対してを実装する必要があります。GetId
EFは、SQL式に変換する方法を知りませんので、関数は、式ツリーに変換することができませんでした。(わかりませんが、エラーが発生する可能性もあります)。この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加