简体   繁体   English

EF核心在保存时忽略导航属性

[英]EF core ignore navigational property on save

It is just an illustratory example, I understand the relations in this example do not make sense perse, but it plots relations in a way I need the solution.这只是一个说明性示例,我理解此示例中的关系本身没有意义,但它以我需要解决方案的方式绘制关系。 So please do not comment about that.所以请不要对此发表评论。

I am searching for a solution in which I can ignore saving a navigational property;我正在寻找一种可以忽略保存导航属性的解决方案;

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);
    }
}

To clearify my question (Using EF 2.2);澄清我的问题(使用 EF 2.2); I want to update the student through it's own StudentRepository.我想通过它自己的 StudentRepository 更新学生。 And when I save a classroom through the ClassRoomRepository and the student might change in any way, I do not want that change to be persisted (even though it is included to be able to 'view' the data).当我通过 ClassRoomRepository 保存教室并且学生可能以任何方式更改时,我不希望该更改被保留(即使包含它以能够“查看”数据)。

I have tried to add the following to the ClassRoomEntityConfiguration:我尝试将以下内容添加到 ClassRoomEntityConfiguration:

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

However this gives the following exception: ... Cannot be used as a property on... because it is configured as a navigation.'但是,这给出了以下例外: ...不能用作...上的属性,因为它被配置为导航。

Another thing I tried is setting the componentmodel readonly attribute on the Students list in the ClassRoom.我尝试的另一件事是在教室的学生列表中设置 componentmodel 只读属性。 This seems to be ignored as well.这似乎也被忽略了。

I call this the goldilocks problem.我称之为金发姑娘问题。 You have a hierarchy of objects (Customer, Order, OrderDetails) and you only want to save at "just the right level" of the object-graph.您有一个对象层次结构(客户、订单、订单详细信息),并且您只想保存在对象图的“恰到好处的级别”。

A work around is to load the object......change only thing things that you care about, then save it.一种解决方法是加载 object……只更改您关心的内容,然后保存。

In the below, I am NOT saving the inputItem.在下面,我没有保存 inputItem。

I am using inputItem to set a small subset of the values of the foundEntity.我正在使用 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;
}

SIDE NOTE:边注:

2.2 is no longer supported (see link below). 2.2 不再受支持(请参阅下面的链接)。 Dot Net Core 2.2 End of Lifetime is listed as "December 23, 2019" Dot Net Core 2.2 End of Lifetime 列为“2019 年 12 月 23 日”

You should upgrade to 3.1 or downgrade to 2.1.您应该升级到 3.1 或降级到 2.1。 (downgrading is counter intuitive I know). (我知道降级是违反直觉的)。

See

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM