EF Core ThenInclude抛异常及Pomelo反向工程1:1关系问题
Let's tackle your two problems step by step:
1. Fixing the The EF.Property<T> method may only be used within LINQ queries. Exception
The error you're seeing when using ThenInclude likely stems from a mismatch between how EF Core interprets your entity relationships and the actual 1:1 relationship you intend. Here's how to resolve it:
Option 1: Correct the Relationship Configuration in Your DbContext
Your current entity classes define a 1:n relationship (Adresse has an ICollection<User>), but you want a 1:1. Update your DbContext's OnModelCreating method to explicitly configure the relationship:
protected override void OnModelCreating(ModelBuilder modelBuilder) { // Configure 1:1 between User and Adresse modelBuilder.Entity<User>() .HasOne(u => u.FidAdresseNavigation) .WithOne(a => a.User) // Replace ICollection<User> with single User reference .HasForeignKey<User>(u => u.FidAdresse) .IsRequired(false); // Matches your nullable FidAdresse property // Keep existing Adresse-PlzOrt n:1 configuration modelBuilder.Entity<Adresse>() .HasOne(a => a.FidPlzOrtNavigation) .WithMany(p => p.Adresse) .HasForeignKey(a => a.FidPlzOrt); // Add other entity configurations as needed... }
You'll also need to modify your Adresse entity class to replace the collection with a single User navigation property:
public partial class Adresse { public Adresse() { // Remove the HashSet<User> initialization } // ... existing properties ... [InverseProperty("FidAdresseNavigation")] public virtual User User { get; set; } // Replace ICollection<User> with User }
After these changes, your original query with ThenInclude should run without throwing the exception.
Option 2: Use Projection as a Temporary Workaround
If you can't modify entity classes immediately, use a projection to explicitly load nested data:
return _context.User .Include(u => u.FidPermissionNavigation) .Include(u => u.FidAdresseNavigation) .Select(u => new User { IdUser = u.IdUser, Email = u.Email, Vorname = u.Vorname, Nachmname = u.Nachmname, FidAdresseNavigation = new Adresse { IdAdresse = u.FidAdresseNavigation.IdAdresse, Strasse = u.FidAdresseNavigation.Strasse, Hausnr = u.FidAdresseNavigation.Hausnr, FidPlzOrtNavigation = u.FidAdresseNavigation.FidPlzOrtNavigation }, FidPermissionNavigation = u.FidPermissionNavigation }) .FirstOrDefault(c => c.IdUser == id);
2. Getting Pomelo to Scaffold 1:1 Relationships Correctly
Pomelo's reverse engineering tool relies on database constraints to identify relationship types. Follow these steps to ensure it recognizes your 1:1 setup:
Step 1: Add a Unique Constraint to Your Database
For a 1:1 relationship where User.FidAdresse references Adresse.IdAdresse, you need a unique constraint on User.FidAdresse to enforce one Adresse per User. Run this MySQL command:
ALTER TABLE `User` ADD CONSTRAINT `UC_User_FidAdresse` UNIQUE (`FidAdresse`);
Step 2: Re-Run Scaffolding with Force
Delete your existing entity classes and DbContext, then re-run the scaffolding command with the --force flag to overwrite files:
dotnet ef dbcontext scaffold "Server=localhost;Database=YourDbName;User=root;Password=YourPassword" Pomelo.EntityFrameworkCore.MySql --force --context-dir Data --output-dir Entities
Step 3: Verify Generated Code
After scaffolding, check the Adresse entity class—it should now have a single User navigation property instead of an ICollection<User>. The DbContext should also automatically configure the 1:1 relationship.
If the scaffolder still doesn't pick up the relationship, manually adjust the entity classes and DbContext configuration as shown in the first section.
内容的提问来源于stack exchange,提问作者axelrotter

