【问题标题】:EF Core. Update Entity without update navigation propertiesEF 核心。更新实体而不更新导航属性
【发布时间】:2023-04-09 02:05:01
【问题描述】:

我正在尝试像这样更新 Entity EF Core 记录:

public class Customer
{
    public int Id { get; set; }
    public int Name { get; set; }
    ...
    public int CountryId { get; set; }
    public virtual Country Country { get; set; }

    public int ZoneId { get; set; }
    public virtual Zone Zone { get; set; }

    public ICollection<Service> Services { get; set; }

    public virtual ICollection<Invoice> Invoices { get; set; }
}

当我调用 Context.Update() 或 Context.Add() 时,还会更新 Zone 和 Country 实体。我不希望虚拟属性更新。我正在尝试通过反射获取虚拟属性以指示 Entry(virtualProperty).State = EntityState.Detached,但我不能。这是我正在尝试的代码。

Type typeOfTEntity = typeof(TEntity);
foreach (var property in typeOfTEntity.GetProperties())
{
    if (property.GetGetMethod().IsVirtual)
    {
        foreach (var member in context.Context.Entry(CurrentItem).Members)
        {
            if (member.Metadata.Name == property.Name)
            {
                context.Context.Entry(member).State = EntityState.Detached;
            }
        }
    }
}

我收到错误:“找不到实体类型'ReferenceEntry'。确保实体类型已添加到模型中。” 我使用 TEntity 是因为我在泛型类中使用了更多实体,并使用相同的方法来更新或添加。 提前致谢。

编辑: 如果我使用非泛型类型的实体(CurrentItem): (CurrentItem 现在是 Customer,而不是 TEntity)

context.Context.Entry(CurrentItem.Country).State = EntityState.Detached;
context.Context.SaveChanges();

现在运行良好。但我需要使用 TEntity。

【问题讨论】:

  • 如何标记所有导航属性unchanged 喜欢context.Context.Entry(member).State = EntityState.Unchanged;
  • 设置状态为Unchanged时也会出现该错误
  • 如果你直接创建导航属性unchanged而不是通过Reflection呢?
  • 对不起,我不知道如何将导航属性设置为不进行反射。
  • 你能分享一下你的模型是什么样子的吗?

标签: c# entity-framework ef-core-2.2


【解决方案1】:

我设法解决了这个问题。不是在 Entry 中插入属性,而是必须插入属性的值。

using (var context = new OpenContext<TContext>(connectionString))
{
    var repository = context.UnitOfWork.GetRepository<TEntity, TKey>();
    repository.Update(CurrentItem);

    // Get the type of TEntity
    Type typeOfTEntity = typeof(TEntity);
    foreach (var property in typeOfTEntity.GetProperties())
    {
        // Check the properties that are virtual and not are HashSet
        if (property.GetGetMethod().IsVirtual && property.PropertyType.GenericTypeArguments.Count() == 0)
        {
            object value = property.GetValue(CurrentItem);
            // Check that value is not null and value type is an Entity
            if (value != null && value.GetType().IsSubclassOf(typeof(Entity<int>)))
            {
                // Set the value that I don't want to change
                context.Context.Entry(value).State = EntityState.Detached;
            }
        }
    }
    context.UnitOfWork.SaveChanges();
}

感谢您的帮助。

【讨论】:

    【解决方案2】:

    如果您不想更新“子实体”,则在获取不想更新的客户时不应包含它们。

    【讨论】:

    • 我需要加载导航实体以在表单中显示它们以绑定具有某些属性的文本框。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-04
    • 1970-01-01
    • 2021-11-10
    • 2021-03-23
    • 2014-05-24
    • 1970-01-01
    • 2021-08-13
    相关资源
    最近更新 更多