Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

builder.Entity<>().Property().Metadata.SetAfterSaveBehavior() cannot be used with .HasOne() on the same prop #33945

Closed
n0099 opened this issue Jun 10, 2024 · 6 comments
Labels
closed-no-further-action The issue is closed and no further action is planned. customer-reported

Comments

@n0099
Copy link

n0099 commented Jun 10, 2024

Ask a question

IMutableProperty.SetAfterSaveBehavior() cannot be used with EntityTypeBuilder<>.HasOne() on the same property.

Include your code

https://github.com/n0099/open-tbm/blob/d482259e42fcc5d016c46f839aecc4552425ae66/c%23/crawler/src/Db/CrawlerDbContext.cs#L72

b.Entity<ReplyPost>().ToTable($"tbmc_f{Fid}_reply")
    .HasOne(e => e.Content).WithOne().HasForeignKey<ReplyContent>(e => e.Pid);
b.Entity<ReplyPost>().Property(e => e.Content).Metadata.SetAfterSaveBehavior(PropertySaveBehavior.Throw);
// ^ exception thrown at this line

or flip order of lines

b.Entity<ReplyPost>().Property(e => e.Content).Metadata.SetAfterSaveBehavior(PropertySaveBehavior.Throw);
b.Entity<ReplyPost>().ToTable($"tbmc_f{Fid}_reply")
    .HasOne(e => e.Content).WithOne().HasForeignKey<ReplyContent>(e => e.Pid);
// ^ exception thrown at this line

Include stack traces

System.InvalidOperationException: The property or navigation 'Content' cannot be added to the 'ReplyPost' type because a property or navigation with the same name already exists on the 'ReplyPost' type.
  at Microsoft.EntityFrameworkCore.Metadata.Internal.InternalEntityTypeBuilder.RemoveMembersInHierarchy(String propertyName, ConfigurationSource configurationSource)
  at Microsoft.EntityFrameworkCore.Metadata.Internal.InternalTypeBaseBuilder.Property(Type propertyType, String propertyName, MemberInfo memberInfo, Nullable`1 typeConfigurationSource, Nullable`1 configurationSource, Boolean skipTypeCheck)
  at Microsoft.EntityFrameworkCore.Metadata.Internal.InternalTypeBaseBuilder.Property(MemberInfo memberInfo, Nullable`1 configurationSource)
  at Microsoft.EntityFrameworkCore.Metadata.Builders.EntityTypeBuilder`1.Property[TProperty](Expression`1 propertyExpression)
  at tbm.Crawler.Db.CrawlerDbContext.OnModelCreating(ModelBuilder b) in /src/Db/CrawlerDbContext.cs:line 78

Include provider and version information

EF Core version: Microsoft.EntityFrameworkCore@8.0.6
Database provider: Npgsql.EntityFrameworkCore.PostgreSQL@8.0.4
Target framework: .NET8
Operating system: Windows 11
IDE: Visual Studio 2022 17.10.1

@ajcvickers
Copy link
Member

@n0099 Using .HasOne(e => e.Content) indicates that e.Content is a navigation pointing to an entity type. Conversely, .Property(e => e.Content) says that this is actually a simple property, not a navigation to another entity type. SetAfterSaveBehavior applies only to simple properties; it can't be applied to an entire entity type. You may be looking for Read-only entity types.

@n0099
Copy link
Author

n0099 commented Jun 11, 2024

So currently it's not possible to ignore any further updates on the related entity being navigatied?

@ajcvickers
Copy link
Member

@n0099 Correct.

@n0099
Copy link
Author

n0099 commented Jun 11, 2024

#29756 (comment)

@n0099 n0099 closed this as not planned Won't fix, can't repro, duplicate, stale Jun 11, 2024
@ajcvickers ajcvickers added closed-no-further-action The issue is closed and no further action is planned. and removed area-model-building labels Jun 15, 2024
@n0099
Copy link
Author

n0099 commented Jul 10, 2024

SetAfterSaveBehavior applies only to simple properties; it can't be applied to an entire entity type.

Does this also applies to SetValueComparer? I'm trying to merge newly inserted related entities that matching the same unique constraint into one entity to prevent duplicated:

b.Entity<LatestReplier>().HasOne<ThreadPost>().WithOne(e => e.LatestReplier).HasForeignKey<ThreadPost>(e => e.LatestReplierId);
b.Entity<ThreadPost>().Property(e => e.LatestReplier).Metadata.SetValueComparer(new ValueComparer<LatestReplier>(
//                                                             ^^^^^^^^^^^^^^^^
// System.InvalidOperationException: The property or navigation 'LatestReplier' cannot be added to the 'ThreadPost' type because a property or navigation with the same name already exists on the 'ThreadPost' type.
    (x, y) =>
        ThreadLatestReplierSaver.UniqueLatestReplier.FromLatestReplier(x)
        == ThreadLatestReplierSaver.UniqueLatestReplier.FromLatestReplier(y),
    i => ThreadLatestReplierSaver.UniqueLatestReplier.FromLatestReplier(i).GetHashCode()));

@ajcvickers
Copy link
Member

@n0099 Yes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed-no-further-action The issue is closed and no further action is planned. customer-reported
Projects
None yet
Development

No branches or pull requests

4 participants