EF5 code先用的ASP.NET Web API:与更新实体许多一对多的关系 [英] EF5 code first with ASP.NET Web API: Update entity with many-to-many relationship

查看:124
本文介绍了EF5 code先用的ASP.NET Web API:与更新实体许多一对多的关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图更新使用的ASP.NET Web API和Entity Framework 5 code-首先我的数据库客户,但它不工作。我的实体是这样的:

I'm trying to update a Customer in my database using ASP.NET Web API and Entity Framework 5 code-first, but it's not working. My entities look like this:

public class CustomerModel
{
    public int Id { get; set; }
    public string Name { get; set; }

    // More fields

    public ICollection<CustomerTypeModel> CustomerTypes { get; set; }
}

public class CustomerTypeModel
{
    public int Id { get; set; }
    public string Type { get; set; }

    [JsonIgnore]
    public ICollection<CustomerModel> Customers { get; set; }
}

没有什么特殊。我已经建立了一个Web界面,用户可以通过提供的名称和检查一个或多个客户类型添加客户。当击中提交按钮,将数据发送到我的Web API方法:

Nothing all that special. I've built a web interface where users can add a customer by supplying the name and checking one or more customer types. When hitting the submit button, the data is sent to my Web API method:

public void Put([FromBody]CustomerModel customer)
{
    using (var context = new MyContext())
    {
        context.Customers.Attach(customer);
        context.Entry(customer).State = EntityState.Modified;
        context.SaveChanges();
    }
}

该更新的客户领域,但相关的客户类型将被忽略。传入客户对象不包含 CustomerTypes 它应该与之关联的列表:

This updates the customer fields, but the related customer types are ignored. The incoming customer object does contain a list of CustomerTypes it should be associated with:

[0] => { Id: 1, Type: "Finance", Customers: Null },
[1] => { Id: 2, Type: "Insurance", Customers: Null }
[2] => { Id: 3, Type: "Electronics", Customers: Null }

但是,而不是看这个列表和添加/删除相关实体,EF只是忽略它。新的关联被忽略,现有关联保持,即使它们应该被删除。

But instead of looking at this list and adding/removing associated entities, EF just ignores it. New associations are ignored and existing associations remain even if they should be deleted.

我插入一个顾客进数据库时也有类似的问题,这时候我调整这些实体的状态 EntityState.Unchanged 是固定的。当然,我想在我的更新方案适用同样的神奇修复:

I had a similar problem when inserting a customer into the database, this was fixed when I adjusted the state of these entities to EntityState.Unchanged. Naturally, I tried to apply this same magic fix in my update scenario:

public void Put([FromBody]CustomerModel customer)
{
    using (var context = new MyContext())
    {
        foreach (var customertype in customer.CustomerTypes)
        {
            context.Entry(customertype).State = EntityState.Unchanged;
        }

        context.Customers.Attach(customer);
        context.Entry(customer).State = EntityState.Modified;
        context.SaveChanges();
    }
}

但EF继续显示相同的行为。

But EF keeps displaying the same behavior.

这是如何解决这一问题的任何想法?或者我应该真的只是做清楚 CustomerTypes 的列表,然后手动手动添加?

Any ideas on how to fix this? Or should I really just do a manual clear to the list of CustomerTypes and then manually add them?

先谢谢了。

JP

推荐答案

这是不是仅通过设置实体状态确实可解。你必须从数据库中首先包括其目前所有类型的加载客户,然后根据客户发布的最新集合类型从删除类型,或添加类型来加载客户。更改跟踪将完成剩下的用来删除连接表项或插入新的条目:

This is not really solvable by only setting entity states. You must load the customer from the database first including all its current types and then remove types from or add types to the loaded customer according to the updated types collection of the posted customer. Change tracking will do the rest to delete entries from the join table or insert new entries:

public void Put([FromBody]CustomerModel customer)
{
    using (var context = new MyContext())
    {
        var customerInDb = context.Customers.Include(c => c.CustomerTypes)
            .Single(c => c.Id == customer.Id);

        // Updates the Name property
        context.Entry(customerInDb).CurrentValues.SetValues(customer);

        // Remove types
        foreach (var typeInDb in customerInDb.CustomerTypes.ToList())
            if (!customer.CustomerTypes.Any(t => t.Id == typeInDb.Id))
                customerInDb.CustomerTypes.Remove(typeInDb);

        // Add new types
        foreach (var type in customer.CustomerTypes)
            if (!customerInDb.CustomerTypes.Any(t => t.Id == type.Id))
            {
                context.CustomerTypes.Attach(type);
                customerInDb.CustomerTypes.Add(type);
            }

        context.SaveChanges();
    }
}

这篇关于EF5 code先用的ASP.NET Web API:与更新实体许多一对多的关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆