【问题标题】:When I call SaveChanges, nothing saved back to the database?当我调用 SaveChanges 时,没有任何内容保存回数据库?
【发布时间】:2018-01-03 20:40:14
【问题描述】:
        editableCustomers = _ctx.Customers.ProjectTo<EditableCustomer>().ToList();
        editableCustomers.First().Name = "changed";
        var customers = _ctx.Customers.ToList();
        Mapper.Map(editableCustomers, customers);

         _ctx.SaveChanges();

我使用 Automapper 执行 EF 实体(在本例中为客户)和可编辑模型(可编辑客户)之间的映射。 为什么 SaveChanges 不起作用?

【问题讨论】:

  • 这是代码原样还是您针对问题对其进行了编辑?因为我不明白您为什么要将客户转换为 EditableCustomers 并再次将其转换回 3 行。
  • 另外,您是否在 SaveChanges 或其他任何地方收到任何错误消息,或者是否所有内容都执行并且您没有看到任何更改?您的实体上是否还有 Id 或其他主键,您可以使用它们在上下文中检索正确的对象吗?
  • customers 现在只是上下文一无所知的分离模型列表。您需要将Attach 他们返回到上下文,因为Modified 不是吗?
  • 我有绑定到可编辑客户列表的 WPF DataGrid。
  • 我没有收到任何错误..

标签: c# entity-framework automapper


【解决方案1】:

通常你会使用 AutoMapper:

var results = Mapper.Map<DestinationType>(source);

或者在你的情况下

var results = Mapper.Map<Customer[]>(editableCustomers);

AutoMapper 也不会更改上下文中的值,而只是将对象从一种形式转换为另一种形式。目前看来,您只是在转换对象,之后对这些对象什么也不做。上下文也不知道这些变化。

通常为了保存更改我宁愿使用这样的代码:

var customer = _ctx.Customers.Single(c => c.Id == modifiedEditableCustomer.Id);
customer.Name = modifiedEditableCustomer.Name;

_ctx.SaveChanges();

modifiedEditableCustomer 是您的 EditableCustomer 之一(您可以遍历它们)。

这是遍历客户并保存更改的对象的另一种方法。如果对象已更改(您需要确定这一点),那么您可以重新附加该对象并将其状态设置为已修改。

foreach (var customer in customers)
{
    if (HasCustomerBeenModified(customer))
    {
        _ctx.Customers.Attach(customer)
        _ctx.Entry(customer).State = System.Data.Entity.EntityState.Modified;
    }

    _ctx.SaveChanges();
}

【讨论】:

  • 为什么不使用 FirstOrDefault ?
  • @MohammadDaliri 通常当我检查 ID 时,我希望我拥有的 ID 是一个有效的 ID,如果我在数据库中找不到它,那么它的异常足以保证例外。在某些情况下,而不是标准的 linq 消息,我更喜欢使用 SingleOrDefault 并手动检查 null 以抛出带有更好消息的自定义异常。至于使用 FirstOrDefault 而不是 SingleOrDefault,如果 FirstOrDefault 找到多个具有相同 ID 的实体,那么它将是有效的,而这永远不会发生。我想知道在那些情况下。但归根结底,这一切都是风格问题……
  • var results = Mapper.Map&lt;Customers&gt;(editableCustomers); 不会是var results = Mapper.Map&lt;Customer[]&gt;(editableCustomers);var results = Mapper.Map&lt;List&lt;Customer&gt;&gt;(editableCustomers); 吗?
  • @pmcilreavy 你完全正确。感谢您发现这一点,我编辑了答案。
  • 感谢您的帮助,我有绑定到可编辑客户列表的 WPF DataGrid,如何知道哪个已修改?
【解决方案2】:

你可以用这种方式代替 Automapper:

        var editableCustomers = _ctx.Customers.ProjectTo<Customer>().ToList();
        editableCustomers.First().Name="changed";
        var customers = _ctx.Customers.ToList();
        foreach (var customer in customers)
        {
            customer.Name = editableCustomers.First(x => x.CustomerId == customer.CustomerId).Name;
        }
        _ctx.SaveChanges();

【讨论】:

  • 感谢 Ali,这行得通,但是如何以大多数性能方式做到这一点?
猜你喜欢
  • 2011-09-23
  • 2011-07-19
  • 2012-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-09
  • 1970-01-01
  • 2020-01-27
相关资源
最近更新 更多