我在使用Entity Framework(6.3)检索关系使用复合键的实体的子集合时遇到问题。在下面的示例中,我正在尝试将Sprint与计划相关联,但Sprints子集合不断变回空白。
// Returns no sprints
var queryUsingSelect = await _dbContext
.Plans
.Select(p => new
{
p,
p.Sprints
})
.ToListAsync();
// Returns a plan without sprints
var queryUsingInclude = await _dbContext
.Plans
.Include(p => p.Sprints)
.ToListAsync();
// Returns me all sprints
var allSprints = await _dbContext
.Plans
.SelectMany(p => p.Sprints)
.ToListAsync();
在上一个查询中,我使用SelectMany测试了它,它确实返回了Sprint,但实际上我需要能够使用Include来完成它。我在同一个项目中遇到了与另一个集合相同的问题,所以这似乎与我的方法一般存在问题。请注意,我已关闭延迟加载以防止意外的n + 1查询。
这是我的代码的精简版:
public class User
{
public int UserId { get; set; }
public string Name { get; set; }
}
public class Aspiration
{
public int AspirationId { get; set; }
public string Title { get; set; }
}
public class Plan
{
public Plan()
{
Sprints = new List<Sprint>();
}
public int UserId { get; set; }
public int AspirationId { get; set; }
public virtual User User { get; set; }
public virtual Aspiration Aspiration { get; set; }
public virtual ICollection<Sprint> Sprints { get; set; }
}
public class Sprint
{
public int SprintId { get; set; }
public int UserId { get; set; }
public int AspirationId { get; set; }
public virtual Plan Plan { get; set; }
public virtual User User { get; set; }
public virtual Aspiration Aspiration { get; set; }
}
public class UserMap : EntityTypeConfiguration<User>
{
public UserMap()
{
Property(t => t.Name)
.HasMaxLength(100)
.IsRequired();
}
}
public class AspirationMap : EntityTypeConfiguration<Aspiration>
{
public AspirationMap()
{
Property(t => t.Title)
.HasMaxLength(100)
.IsRequired();
}
}
public class PlanMap : EntityTypeConfiguration<Plan>
{
public PlanMap()
{
HasKey(s => new { s.UserId, s.AspirationId });
HasRequired(s => s.User)
.WithMany()
.HasForeignKey(s => s.UserId);
HasRequired(s => s.Aspiration)
.WithMany()
.HasForeignKey(s => s.AspirationId);
}
}
public class SprintMap : EntityTypeConfiguration<Sprint>
{
public SprintMap()
{
HasRequired(s => s.User)
.WithMany()
.HasForeignKey(s => s.UserId);
HasRequired(s => s.Aspiration)
.WithMany()
.HasForeignKey(s => s.AspirationId);
HasRequired(s => s.Plan)
.WithMany(d => d.Sprints)
.HasForeignKey(s => new { s.AspirationId, s.UserId });
}
}
public class MyDbContext : DbContext
{
static MyDbContext()
{
Database.SetInitializer<MyDbContext>(null);
}
public MyDbContext()
: base(DbConstants.ConnectionStringName)
{
Configuration.LazyLoadingEnabled = false;
}
public DbSet<User> Users { get; set; }
public DbSet<Aspiration> Aspirations { get; set; }
public DbSet<Plan> Plans { get; set; }
public DbSet<Sprint> Sprints { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder
.Map(new UserMap())
.Map(new AspirationMap())
.Map(new PlanMap())
.Map(new SprintMap())
;
}
}
答案 0 :(得分:1)
好吧,我在你的映射中看到了一些错误。
Plan
中Sprint
的FK必须与Plan
的PK具有相同的顺序。所以替换这个:
HasRequired(s => s.Plan)
.WithMany(d => d.Sprints)
.HasForeignKey(s => new { s.AspirationId,s.UserId });
为此:
HasRequired(s => s.Plan)
.WithMany(d => d.Sprints)
.HasForeignKey(s => new { s.UserId, s.AspirationId });
进行这些更改后,我尝试运行您的代码,一切正常。