WebAPI [FromBody]作为EF模型的行为就像它是不可变的

时间:2018-04-30 23:36:35

标签: c# entity-framework asp.net-web-api2

我有一个使用Entity Framework中的复杂类型的WebAPI控制器。当我收到对象时,我会检查它是否存在。如果不是,我想创建一个新的。在我创建新的之前,我想为对象添加一些额外的值。如果我添加断点和手表,我可以看到值,看起来它已经改变了。但是这个值并没有进入数据库。

[Authorize(Roles ="customerprofileuser")]
[Route("api/CustomerProfile/Save")]
[HttpPost]
public IHttpActionResult SaveCustomerProfile([FromBody] MERP.Customer _input)
{
    Models.Message.Response _return = new Models.Message.Response();
    _return.Message = "Profile Saved!";
    _return.Now = DateTime.Now;

    try {
        ERPEntities ent = new ERPEntities();
        var cust = ent.Customers.AsNoTracking().Where(w => w.ID == _input.ID).FirstOrDefault();

        if (cust == null)
        {
            _input.ID = Guid.NewGuid();
            _input.Alias = getCustomerNumberNext(_input.Type);
            _input.CreatedOn = DateTime.Now;

            ent.Customers.Add(_input);
        }
        else
        {
            ent.Customers.Attach(_input);
            ent.Entry(_input).State = System.Data.Entity.EntityState.Modified;
        }
        _return.ResponseObject = _input.ID.ToString();
        ent.SaveChanges();
    }
    catch (Exception ex)
    {
        _return.Message = ex.Message;
        _return.Severity = 3;
    }
    return Ok(_return);
}

如果我将值映射到这样的新对象,一切都按预期工作。

                var val = new Customer();
                val.ID = Guid.NewGuid();
                val.Active = _input.Active;
                val.Alias = getCustomerNumberNext(_input.Type);
                val.CreatedOn = DateTime.Now;

                ent.Customers.Add(val);

我宁愿不将每个属性映射到新的对象属性。有没有办法绕过这种行为?

以下是我的实体模型中自动生成的Customer类的示例。

public partial class Customer
{
    public System.Guid ID { get; set; }
    public string Name { get; set; }
    public Nullable<System.Guid> Type { get; set; }
    public string Alias { get; set; }
    public string Website { get; set; }
    public string Note { get; set; }
    public string Email { get; set; }
    public Nullable<System.Guid> Salesman { get; set; }
    public Nullable<System.Guid> SalesRegion { get; set; }
    public Nullable<bool> Active { get; set; }
    public string LinkedIn { get; set; }
    public string Facebook { get; set; }
    public string Twitter { get; set; }
    public string GoldmineFK { get; set; }
    public string SalesFK { get; set; }
    public string InventoryFK { get; set; }
    public Nullable<System.Guid> Industry { get; set; }
    public Nullable<System.Guid> Lead { get; set; }
    public Nullable<System.Guid> Show { get; set; }
    public Nullable<System.Guid> Territory { get; set; }
    public Nullable<System.DateTime> CreatedOn { get; set; }
}

这是getCustomerNumberNext函数

    private string getCustomerNumberNext(Guid? companyid)
    {
        ERPEntities ent = new ERPEntities();
        var _prefix = (from p in ent.CompanyLookups
                       where p.Type == "CustomerNumberPrefix"
                       select p.Value.ToString()).FirstOrDefault();

        var _number = (from p in ent.CompanyLookups
                       where p.Type == "CustomerNumberSequence"
                       select p.Value.ToString()).FirstOrDefault();

        var _newNumber = Convert.ToInt32(_number) + 1;

        try
        {
            var _update = (from p in ent.CompanyLookups
                           where p.Type == "CustomerNumberSequence"
                           select p).FirstOrDefault();
            _update.Value = _newNumber.ToString();
            ent.SaveChanges();
        }
        catch (Exception ex)
        { return ex.Message; }

        return _prefix + _number;
    }

编辑:C#代码按预期工作。问题在于客户的数据往往不完整和不完整。

1 个答案:

答案 0 :(得分:0)

我相信你的问题中有一个拼写错误,上面写着“它确实会进入数据库”,但我相信你的意思是“不会进入数据库”

根据这个假设,我尝试在本地运行类似的代码,并能够按预期保存值。主要区别在于Alias是我的代码中的整数,我假设它是代码中的复杂类。以下是将值成功保存到数据库的代码,

public class HomeController : ApiController
{
    [HttpPost]
    [Route("api/CustomerProfile/Save")]
    public IHttpActionResult SaveCustomerProfile([FromBody] Customer _input)
    {
        masterEntities masterEntities = new masterEntities();
        var cust = masterEntities.Customers.AsNoTracking().Where(w => w.ID == _input.ID).FirstOrDefault();

        if (cust == null)
        {
            _input.ID = Guid.NewGuid();
            _input.Alias = 0;
            _input.CreatedOn = DateTime.Now;

            masterEntities.Customers.Add(_input);
        }
        else
        {
            masterEntities.Customers.Attach(_input);
            masterEntities.Entry(_input).State = System.Data.Entity.EntityState.Modified;
        }

        masterEntities.SaveChanges();

        return Ok();
    }
}

以下是生成的Customer类的内容,

public partial class Customer
{
    public System.Guid ID { get; set; }
    public bool Active { get; set; }
    public Nullable<int> Alias { get; set; }
    public Nullable<System.DateTime> CreatedOn { get; set; }
}

您可以使用代码中的Customer和Alias类更新您的问题吗?我可以尝试重现该问题吗?

另一方面,我建议改变

var cust = ent.Customers.AsNoTracking().Where(w => w.ID == _input.ID).FirstOrDefault();

var cust = ent.Customers.AsNoTracking().FirstOrDefault(w => w.ID == _input.ID);