からautomapperソートを聞かせ: あなたはインターフェイス
からDTOの継承を使用すると、DTOを持っていると言うことがあります:
public interface IFooDTO
{
int Id { get; set;}
string Name { get; set;}
}
public class FooDTO : IFooDTO
{
public int Id { get; set;}
public string Name { get; set; }
}
は、次に、あなたのエンティティを持っている
public class FooEntity
{
public int Id;
public string name;
}
は、そのようにfooというインターフェースを継承しているようなあなたのアダプタを作成:
public class FooAdapter : IFooDTO
{
FooEntity entity;
FooAdapter(FooEntity entity)
{
this.entity = entity;
}
public int Id
{
get {return this.entity.Id;}
set {/*Do nothing set by EF*/}
}
public string Name
{
get {return this.entity.Name;}
set {this.entity.Name = value; }
}
public void Apply(FooDTO foo)
{
//I don't remember if this is the correct order but you get the gyst
this._mapper.Map<IFooDTO, IFooDTO>(this, foo);
}
}
次に、あなただけのマッパーでDTOあなたにあなたのIdtoからマップする必要があります。
使用法:
public ActionResult PutFoo(int id, FooDTO foo)
{
var entity = context.Foos.FirstOrDefault(x => x.Id == id);
var adapter = new FooAdapter(entity);
adapter.Apply(foo);
//Entity has been updated and has original changes
}
EDIT
子供は細かい作業だけ同じアダプタパターンを使用し、このためのセッターは多くのコードですが、エンティティの同期
public BarDTO childBar
{
get { return new BarAdapter(this.entity.Bar).ToDTO(); }
set { new BarAdapter(this.entity.Bar).Apply(value) }
}
:
を
public static void Sync<TEntity, TEntityKey, TDTO>(this ICollection<TEntity> entityCollection, ICollection<TDTO> dtoCollection,
Func<TEntity> entityConstructor, Action<TDTO, TEntity> copyAction,
Action<TEntity> onDeleteAction,
Func<TEntity, TEntityKey> entityKeySelector,
Func<TDTO, TEntityKey> dtoKeySelector)
where TEntity : class
where TEntityKey : struct
{
dtoCollection = dtoCollection ?? new TDTO[] { };
except = except ?? new TEntityKey[] { };
var dtoIds = dtoCollection.Select(dto => dtoKeySelector(dto)).ToHashSet();
foreach (var entity in entityCollection.Where(x => false == dtoIds.Contains(entityKeySelector(x))).ToArray())
{
onDeleteAction(entity);
entityCollection.Remove(entity);
}
var entityCollectionMap = entityCollection.ToDictionary(x => entityKeySelector(x));
foreach (var dtoItem in dtoCollection)
{
TEntity entity = null;
if (dtoKeySelector(dtoItem).HasValue)
{
entity = entityCollectionMap.ContainsKey(dtoKeySelector(dtoItem)) ? entityCollectionMap[dtoKeySelector(dtoItem)] : default(TEntity);
}
if (null == entity)
{
entity = entityConstructor();
entityCollection.Add(entity);
}
copyAction(dtoItem, entity);
}
}
これは非常に興味深い...ありがとうございます。また、オブジェクト内の子オブジェクトとリストに対してこの作業を行うことはできますか? automapperを実行し、DTOにない(IDと一致していない)リストから項目を削除しますか? – Gillardo
@ user2736022この回答は役に立ちそうです、私は子オブジェクトの答えを更新しました。うまくいけば、これはあなたのオリジナル投稿を満足させます。あなたは上記のことを行うためにグローバル同期メソッドを使用することができます。ユニオンとICollectionを更新するだけで、多くの余分なコードがわかります。遅れている場合は、別のアップデートに入れます –
getterは簡単です{return this.entity.Bars.Select(b =>新しいBarAdapter(b).ToDTO())。ToList(); } ' –