【问题标题】:Add member to virtual collection using Entity Framerwork Core使用 Entity Framework Core 将成员添加到虚拟集合
【发布时间】:2021-03-22 15:47:25
【问题描述】:

我正在尝试将 Customer 添加到 CustomerCategoryCustomers 集合中,但消息引发异常

数据库操作预计会影响 1 行,但实际上会影响 0 行。数据可能已被修改或删除,因为实体 已加载。

我在 .NET 5.0 类库中使用 Microsoft.EntityFrameworkCore.Sqlite Version 5.0.0 Microsoft.EntityFrameworkCore.Proxies Version 5.0.0

我已尝试简化类以帮助确定错误的原因,但没有成功。这是我目前所拥有的。

public class Customer
{
    public Guid CustomerId { get; set; } = Guid.NewGuid();
    public Guid CategoryId { get; set; }
    public virtual CustomerCategory Category { get; set; }
    public string FileAs { get; set; }
}

public class CustomerCategory
{
    public Guid CategoryId { get; set; } = Guid.NewGuid();
    public string CategoryCode { get; set; }
    public virtual ICollection<Customer> Customers { get; set; }
}

public class DataContext : DbContext
{
    public DbSet<Customer> Customers { get; set; }
    public DbSet<CustomerCategory> CustomerCategories { get; set; }
}

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseSqlite(DataService.SqliteConnectionString);
    optionsBuilder.UseLazyLoadingProxies();
    base.OnConfiguring(optionsBuilder);
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Customer>()
                .HasOne(cus => cus.Category)
                .WithMany(cat => cat.Customers)
                .HasForeignKey(nameof(Customer.CategoryId));
    modelBuilder.Entity<CustomerCategory>()
                .HasKey(e => e.CategoryId);
}

在这个sn-p中调用db.SaveChanges()时抛出异常:

public static void AddCustomer()
{
    using (DataContext db = new())
    {
        try
        {
            Guid cat1Guid = new Guid("FA754EE8-B343-4E0B-9A11-AA066E4678C0");
            CustomerCategory category = db.CustomerCategories.Find(cat1Guid);
            Customer customer = new();
            customer.FileAs = "Fred-1";
            category.Customers.Add(customer);
            db.SaveChanges();
        }
        catch (Exception ex)
        { }
    }
}

如何使用 Entity Framework Core 将成员添加到虚拟集合?

【问题讨论】:

  • 首先删除catch (Exception ex){ },永远不要使用它。隐藏异常不会让问题消失,这意味着您无法修复它们。其次,发布实际的完整异常文本,而不仅仅是消息。我怀疑您遇到了 DbConcurrencyException。如文本所述,当其他连接在实体加载和保存期间修改实体时,就会引发这种情况。第三,您没有发布表的架构(CREATE TABLE 语句、外键约束),所以必须猜测发生了什么
  • 我的(相当有把握的)猜测——您从未将Customer 添加到数据库中,因此您不能只在Category.Customers 中添加与它的关系。调用category.Customers.Add(customer); 将一个条目添加到CategoryCustomers。为此,它需要Customers 表中的有效相关条目,但此时不存在。在使用db.Customers.Add(customer); 调用SaveChanges 之前添加客户

标签: entity-framework-core


【解决方案1】:

首先,永远不要使用catch(Exception exc){}。这只会使问题更难发现和解决。

在存储更改之前将新的 Customer 对象添加到数据库。在新客户对象上设置类别,而不是反过来:

Customer customer = new();
customer.FileAs = "Fred-1";
customer.Category=category;
db.Customers.Add(customer);

db.SaveChanges(); 

您可以通过直接设置CategoryID 来避免完全加载类别:

using DataContext db = new();
Guid cat1Guid = new Guid("FA754EE8-B343-4E0B-9A11-AA066E4678C0");
Customer customer = new() 
{
    CategoryID=cat1Guid,
    FileAs = "Fred-1"
};
db.Customers.Add(customer);
db.SaveChanges();

调用category.Customers.Add(customer); 告诉EF 这两个实体是相关的,它不会创建新的相关实体。在客户端,EF 无法知道 Customer 是新对象还是现有对象,尤其是,因为它具有非默认 ID。那个电话只是要求 EF 更新 Customer 的类别还是插入一个新的类别?没有办法知道。

【讨论】:

    猜你喜欢
    • 2020-04-23
    • 2020-05-27
    • 1970-01-01
    • 2021-03-31
    • 2017-02-11
    • 2016-08-04
    • 2017-02-06
    • 1970-01-01
    • 2020-12-14
    相关资源
    最近更新 更多