如何使用代码优先和流利的 api 设置这些表关系的映射?
我为创建的所有三个实体都有一个 poco,但大多数人没有用于“中间”表(PlanUser)的 poco,所以我找不到一个很好的例子。我需要告诉 EF 将PlanUser.PlanCustomerId列映射到Plan.CustomerId但它要么不返回正确的结果,要么在当前设置中,Plan的映射会引发错误:
“指定的关联外键列‘CustomerId’无效。指定的列数必须与主键列数匹配。”
public class PlanUserMap : EntityTypeConfiguration<PlanUser>
{
public PlanUserMap()
{
this.ToTable("PlanUser");
this.HasKey(c => new { c.CustomerId, c.PlanCustomerId });
this.HasRequired(c => c.Plan).WithMany().HasForeignKey(x => x.CustomerId).WillCascadeOnDelete(false);
this.HasRequired(c => c.Customer).WithMany().HasForeignKey(x => x.CustomerId).WillCascadeOnDelete(false);
}
}
public class PlanMap : EntityTypeConfiguration<Plan>
{
public PlanMap()
{
this.ToTable("Plan");
this.HasKey(c => c.CustomerId);
// the below line returns only 1 row for any given customer even if there are multiple PlanUser rows for that customer
//this.HasMany(c => c.PlanUsers).WithRequired().HasForeignKey(c => c.PlanCustomerId);
// this throws an error
this.HasMany(c => c.PlanUsers).WithMany().Map(m => m.MapLeftKey("PlanCustomerId").MapRightKey("CustomerId"));
}
}
public partial class CustomerMap : EntityTypeConfiguration<Customer>
{
public CustomerMap()
{
this.ToTable("Customer");
this.HasKey(c => c.Id);
this.HasMany(c => c.PlanUsers).WithRequired().HasForeignKey(c => c.CustomerId);
}
}
@Slauma,sql profiler 显示正在执行的这些查询。除了客户 ID 1 之外,第二个还应包括客户 ID 43,但它没有。我不知道为什么它不检索第二行。
exec sp_executesql N'SELECT
[Extent1].[CustomerId] AS [CustomerId],
[Extent1].[PlanCustomerId] AS [PlanCustomerId],
[Extent1].[CreatedOnUtc] AS [CreatedOnUtc],
[Extent1].[IsSelected] AS [IsSelected],
[Extent1].[IsDeleted] AS [IsDeleted],
[Extent1].[AccessRights] AS [AccessRights]
FROM [dbo].[PlanUser] AS [Extent1]
WHERE [Extent1].[CustomerId] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=43
exec sp_executesql N'SELECT
[Extent1].[CustomerId] AS [CustomerId],
[Extent1].[Name] AS [Name],
[Extent1].[PlanTypeId] AS [PlanTypeId],
[Extent1].[OrderId] AS [OrderId],
[Extent1].[CreatedOnUtc] AS [CreatedOnUtc],
[Extent1].[IsActive] AS [IsActive]
FROM [dbo].[Plan] AS [Extent1]
WHERE [Extent1].[CustomerId] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=1
以下是导致查询执行的 C# 代码:
public List<Plan> GetPlans()
{
List<Plan> plans = new List<Plan>();
// add each plan they have access rights to to the list
foreach (var accessiblePlan in Customer.PlanUsers)
{
plans.Add(accessiblePlan.Plan);
}
return plans;
}