【问题标题】:EF core ignore navigational property on saveEF核心在保存时忽略导航属性
【发布时间】:2020-07-18 16:30:10
【问题描述】:

这只是一个说明性的例子,我理解这个例子中的关系本身没有意义,但它以我需要解决方案的方式绘制关系。所以请不要对此发表评论。

我正在寻找可以忽略保存导航属性的解决方案;

public class ClassRoom {
    public Guid Id { get; set; }
    public Guid? ClassRoomInformationId { get; set; }
    
    public virtual ClassRoomInformation { get; set; }
    public virtual Collection<Student> Students { get; set; 
}

public class Student {
    public Guid Id { get; set; }
    public Guid? ClassRoomId { get; set; }
    public Guid? StudentInformationId { get; set; }

    public virtual StudentInformation { get; set; }
}

public class StudentEntityConfiguration : IEntityTypeConfiguration<Student> {
    public void Configure(EntityTypeBuilder<Student> builder) {
        builder.ToTable("Student");
        builder.HasKey(s => s.Id);

        builder.HasOne(s => s.StudentInformation)
            .WithOne()
            .HasForeignKey<Student>(s => s.StudentInformationId);
    }
}

public class ClassRoomEntityConfiguration : IEntityTypeConfiguration<ClassRoom> {
    public void Configure(EntityTypeBuilder<ClassRoom> builder) {
        builder.ToTable("ClassRoom");
        builder.HasKey(c => c.Id);

        builder.HasOne(c => c.ClassRoomInformation)
            .WithOne()
            .HasForeignKey<ClassRoom>(c => c.ClassRoomInformationId);

        builder.HasMany(c => c.Students)
            .WithOne()
            .HasForeignKey(c => c.ClassRoomInformation);
    }
}

澄清我的问题(使用 EF 2.2);我想通过它自己的 StudentRepository 更新学生。当我通过 ClassRoomRepository 保存教室并且学生可能以任何方式发生变化时,我不希望该更改被保留(即使包含它以能够“查看”数据)。

我已尝试将以下内容添加到 ClassRoomEntityConfiguration:

//BeforeSaveBehavior neither works
builder.Property(c => c.Students).Metadata.AfterSaveBehavior = PropertySaveBehavior.Ignore;

但是,这会产生以下异常: ...不能用作...上的属性,因为它被配置为导航。'

我尝试的另一件事是在教室的学生列表中设置 componentmodel 只读属性。这似乎也被忽略了。

【问题讨论】:

  • 我认为主要的设计问题是您使用完整实体进行 CRUD 操作,这意味着您无法控制将输入哪些修改。排除所有存储库中的所有“非法”更改是不可行的。

标签: c# entity-framework-core


【解决方案1】:

我称之为金发姑娘问题。您有一个对象层次结构(Customer、Order、OrderDetails)并且您只想保存在对象图的“恰到好处的级别”。

解决方法是加载对象......只更改您关心的内容,然后保存它。

在下面,我没有保存 inputItem。

我正在使用 inputItem 设置 foundEntity 值的一小部分。

public async Task<MyThing> UpdateAsync(MyThing inputItem, CancellationToken token)
{
    int saveChangesAsyncValue = 0;
    MyThing foundEntity = await this.entityDbContext.MyThings.FirstOrDefaultAsync(item => item.MySurrogateKey == inputItem.MySurrogateKey, token);
    if (null != foundEntity)
    {

         /* alter JUST the things i want to update */
        foundEntity.MyStringPropertyOne = inputItem.MyStringPropertyOne;
        foundEntity.MyStringPropertyTwo = inputItem.MyStringPropertyTwo;


        this.entityDbContext.Entry(foundEntity).State = EntityState.Modified;

        saveChangesAsyncValue = await this.entityDbContext.SaveChangesAsync(token);

        /* an exception here would suggest another process changed the "context" but did not commit the changes (usually by SaveChanges() or SaveChangesAsync() */
        if (1 != saveChangesAsyncValue)
        {
            throw new ArgumentOutOfRangeException(string.Format("The expected count was off.  Did something else change the dbcontext and not save it?  {0}", saveChangesAsyncValue), (Exception)null);
        }
    }
    else
    {
        ArgumentOutOfRangeException argEx = new ArgumentOutOfRangeException(string.Format(" SAD FACE {0} ", entity.MyThingKey), (Exception)null);
        this.logger.LogError(argEx);
        throw argEx;
    }

    return foundEntity;
}

旁注:

2.2 不再受支持(请参阅下面的链接)。 Dot Net Core 2.2 End of Lifetime 列为“2019 年 12 月 23 日”

您应该升级到 3.1 或降级到 2.1。 (我知道降级是反直觉的)。

https://dotnet.microsoft.com/platform/support/policy/dotnet-core

【讨论】:

  • 感谢您的思考,但我希望尽可能接近默认解决方案,而不是“映射每个”属性。对金发姑娘的感觉很好;)
  • //quote//学生可能会以任何方式改变,我不希望这种改变被持久化//。默认行为是..如果您在上下文中更改对象..它会被持久化。所以你可能会要求一些不存在的东西。但也许你会得到答案,我们都会学到一些东西。恕我直言,我的回答很有效,而且很直接......祝你好运。
  • 我明白,这是一个很好的解决方法,但是我希望可以通过属性元数据示例之类的配置或通过属性进行设置:)
猜你喜欢
  • 2018-10-22
  • 2021-08-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-30
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
相关资源
最近更新 更多