簡體   English   中英

.Net Entity Framework 更新分離的孩子

[英].Net Entity Framework Update Detached Children

所以我有例如這些模型:

public class Account 
{
    public Guid ID {get;set;}

    [ForeignKey("Profile")]
    public Guid? ProfileId {get;set;}
    public virtual Profile Profile {get;set;}
    ......
}

public class Profile
{
    public Guid ID {get;set;}

    [ForeignKey("Account")]
    public Guid AccountId {get;set;}
    public virtual Account Account {get;set;}
}

然后我有一個從 controller 請求的視圖 (html)。

public class ExController : ApiController
{
    public async Task<Account> GetAccount(Guid id)
    {
        return await db.Accounts.Where(m => m.ID == id).FirstOrDefaultAsync();
    }
}

然后 html 視圖編輯/更新帳戶實體,然后再次將其傳遞給 controller 以保存到數據庫中。 如果我只是從視圖中保存原始傳遞的實體,則Profile將被視為新實體。 這不是我想要的,我想要更新而不是添加AccountAccount.Profile

例如:

public async Task UpdateModel(Account model)
{
    db.Accounts.Attach(model);
    db.Entry(model).State = EntityState.Modified;
    await db.SaveChangesAsync();
}

model中的子配置文件將被視為新實體。

我怎樣才能更新子實體呢?


編輯

所以我的目的不是使用實體作為view model 我正在開發一個 object 映射器,其中 map 從 vm 到 model 的所有屬性,反之亦然。

像這樣的東西:

vm.MapTo<Model>(ref existing);

問題是 EF 總是將從view model映射的子實體視為新實體。


編輯

這是我的映射 function

    public void MapTo<T>(ref T instance)
    {
        var fromProperties = this.GetType().GetProperties();
        var toProperties = typeof(T).GetProperties();

        foreach (PropertyInfo prop in fromProperties)
        {
            string propName = prop.Name;
            if (prop.CustomAttributes.Count() > 0)
            {
                MapToAttribute mapAttribute = (MapToAttribute)Attribute.GetCustomAttribute(prop, typeof(MapToAttribute));
                AutoGeneratedAttribute autoGeneratedAttribute = (AutoGeneratedAttribute)Attribute.GetCustomAttribute(prop, typeof(AutoGeneratedAttribute));

                if (mapAttribute != null)
                    propName = mapAttribute.MappedProperty;

                if (autoGeneratedAttribute != null)
                    propName = "";
            }
            PropertyInfo mappedProp = toProperties.Where(m => m.Name == propName).FirstOrDefault();

            if (mappedProp != null)
            {
                object value = prop.GetValue(this);
                if (value != null && value.GetType() == typeof(DateTime))
                {
                    DateTime dateValue = ((DateTime)(value)).ToUniversalTime();
                    mappedProp.SetValue(instance, dateValue);
                }
                else if (value != null && value.GetType() == typeof(DateTime?))
                {
                    DateTime? dateValue = ((DateTime?)(value)).Value.ToUniversalTime();
                    mappedProp.SetValue(instance, dateValue);
                }
                else
                {
                    mappedProp.SetValue(instance, value);
                }
            }
        }
    }

從 UI 接受 model 時要小心。 這不是一個好習慣。 通過這種方式,您可以選擇存儲的內容,也可以對其進行驗證。

再次從 db 查詢項目

public async Task UpdateModel(Account model)
{
    var dbItem = await db.Accounts.Include(x=>x.Profile).FirstOrDefaultAsync(m => m.ID == model.Id);

    //map values from model to dbItem 

    await db.SaveChangesAsync();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM