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

abp ef Required one-to-many with shadow foreign key insert error #20100

Open
1 task done
842549829 opened this issue Jun 25, 2024 · 6 comments
Open
1 task done

abp ef Required one-to-many with shadow foreign key insert error #20100

842549829 opened this issue Jun 25, 2024 · 6 comments

Comments

@842549829
Copy link

842549829 commented Jun 25, 2024

Is there an existing issue for this?

  • I have searched the existing issues

Description

abp ef Required one-to-many with shadow foreign key insert error.
If the column below abp is not used, it can be inserted normally.

Error message:
The instance of entity type 'Course' cannot be tracked because another instance with the same key value for {'Id'} is already being tracked. When attaching existing entities, ensure that only one entity instance with a given key value is attached. Consider using 'DbContextOptionsBuilder.EnableSensitiveDataLogging' to see the conflicting key values.

Example:

builder.Entity<Course>(b =>
 {
       b.HasOne(x => x.Teacher).WithMany(t => t.Courses);
 });
public class Teacher : FullAuditedAggregateRoot<Guid>
 {
       public string Name { get; set; }

       public string Title { get; set; }

       public ICollection<Course> Courses { get; set; } = new List<Course>();
 }
public class Course : FullAuditedAggregateRoot<Guid>
    {
        public string Name { get; set; }

        public Teacher? Teacher { get; set; }
  }

Test:

 public class TeacherAppService : CrudAppService<
          Teacher, 
          TeacherDto, 
          Guid, 
          PagedAndSortedResultRequestDto, 
          CreateUpdateTeacherDto>
  {
      public TeacherAppService(IRepository<Teacher, Guid> repository) : base(repository)
      {
          Repository=repository;
      }

      public IRepository<Teacher, Guid> Repository { get; }

      public override async Task<TeacherDto> CreateAsync(CreateUpdateTeacherDto input)
      {
          var teacher = new Teacher
          {
              Name = "My Name",
              Title = "My Title"
          };
          var course1 = new Course { Name = "Course1" };
          var course2 = new Course { Name = "Course2" };
          teacher.Courses.Add(course1);
          teacher.Courses.Add(course2);
          await Repository.InsertAsync(teacher);
          return null;
      }
}

Reproduction Steps

No response

Expected behavior

No response

Actual behavior

No response

Regression?

No response

Known Workarounds

No response

Version

8.0

User Interface

Common (Default)

Database Provider

EF Core (Default)

Tiered or separate authentication server

Tiered

Operation System

Windows (Default)

Other information

No response

@842549829 842549829 added the bug label Jun 25, 2024
@mrh520
Copy link

mrh520 commented Jun 25, 2024

try:

public class Teacher : FullAuditedAggregateRoot
{
public string Name { get; set; }

   public string Title { get; set; }

   [ForeignKey("TeacherId")]
   public ICollection<Course> Courses { get; set; } 

}

@842549829
Copy link
Author

The Microsoft website documentation describes this configuration method as
Required one-to-many with shadow foreign key
https://learn.microsoft.com/en-us/ef/core/modeling/relationships/one-to-many#required-one-to-many-with-shadow-foreign-key

@mrh520
Copy link

mrh520 commented Jun 28, 2024

public class TeacherAppService : CrudAppService<
     Teacher,
     TeacherDto,
     Guid,
     PagedAndSortedResultRequestDto,
     CreateUpdateTeacherDto>
{
    public TeacherAppService(IRepository<Teacher, Guid> repository) : base(repository)
    {
        Repository=repository;
    }

    public IRepository<Teacher, Guid> Repository { get; }

    public override async Task<TeacherDto> CreateAsync(CreateUpdateTeacherDto input)
    {
        var teacher = new Teacher
        {
            Name = "My Name",
            Title = "My Title"
        };
        var course1 = new Course { Name = "Course1",Id=Guid.NewGuid() };
        var course2 = new Course { Name = "Course2", Id=Guid.NewGuid() };
        teacher.Courses.Add(course1);
        teacher.Courses.Add(course2);
        await Repository.InsertAsync(teacher);
        return null;
    }
}

@842549829
Copy link
Author

I don't understand what you mean

@mrh520
Copy link

mrh520 commented Jun 28, 2024

Assign a value to the Id

@842549829
Copy link
Author

I know assigning an Id will work but what I want is for the framework to generate the Id for me by default

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants