エンティティ フレームワーク メソッドDbPropertyValues.SetValuesを逆に使用して、エンティティ内のプロパティの現在の値に基づいて、ビュー モデルまたはデータ転送オブジェクトなどのオブジェクトの値を設定できますか?
これは、SetValues を DTO と共に使用して、DTO のクラス定義で指定したプロパティのみを更新する方法の一例です。
public Address UpdateAddress(Address address)
{
using (var context = new OrdersContext())
{
var targetAddress = context.Addresses.FirstOrDefault(a => a.AddressID == address.AddressID && a.User.UserName.ToLower() == HttpContext.Current.User.Identity.Name.ToLower());
if (targetAddress == null) return null; // Address not found or user doesn't own this address.
context.Entry(targetAddress).CurrentValues.SetValues(address);
context.SaveChanges();
return new Address
{
AddressID = targetAddress.AddressID,
AddressLine1 = targetAddress.AddressLine1,
AddressLine2 = targetAddress.AddressLine2,
City = targetAddress.City,
State = targetAddress.State,
ZipCode = targetAddress.ZipCode
};
}
}
public class Address
{
public int AddressID { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
// public string UserID { get; set; } // UserID is excluded from the view model so that it cannot be updated.
}
SetValues のドキュメントが示すように
指定されたオブジェクトは、任意のタイプにすることができます。ディクショナリ内のプロパティ名と一致し、読み取り可能な名前を持つオブジェクトのすべてのプロパティが読み取られます。他のプロパティは無視されます。これにより、単純なデータ転送オブジェクト (DTO) からプロパティをコピーできます。
SetValues を逆に使用してエンティティから DTO の値を設定し、値を手動で 1 つずつ設定する必要がないようにすることはできますか? または、SetValues のように機能するが逆の別の方法はありますか?
ToObject という別のDbPropertyValues メソッドがありますが、DTO では機能しません。
私はこのようなことをしたいと思います:
public Address UpdateAddress(Address address)
{
using (var context = new OrdersContext())
{
var targetAddress = context.Addresses.FirstOrDefault(a => a.AddressID == address.AddressID && a.User.UserName.ToLower() == HttpContext.Current.User.Identity.Name.ToLower());
if (targetAddress == null) return null; // Address not found or user doesn't own this address.
context.Entry(targetAddress).CurrentValues.SetValues(address);
context.SaveChanges();
return context.Entry(targetAddress).ToObject(new Address());
}
}
ありがとう!