一对一 HasRequired 配置不起作用
One to One HasRequired configuration not working
我有两组对象:Coupon
和 DiscountScheme
。
每个都有一个 {Type}Action
的连接对象和相同的配置。
请求 Coupon
时,我没有得到任何回复,
但是 DiscountScheme
的相同查询按预期工作
类 的精简版(table 的完整代码和 sql 可以在 here 中找到):
public class CouponAction
{
public int Id { get; set; }
public virtual Coupon Coupon { get; set; }
}
public class Coupon
{
public int Id { get; set; }
public virtual CouponAction Action { get; set; }
}
public class DiscountSchemeAction
{
public int Id { get; set; }
public virtual DiscountScheme DiscountScheme { get; set; }
}
public class DiscountScheme
{
public int Id { get; set; }
public virtual DiscountSchemeAction Action { get; set; }
}
配置:
public class CouponActionMap : EntityTypeConfiguration<CouponAction>
{
public CouponActionMap()
{
ToTable("CouponAction");
}
}
public class CouponMap : EntityTypeConfiguration<Coupon>
{
public CouponMap()
{
ToTable("Coupon");
HasRequired(c => c.Action);
}
}
public class DiscountSchemeActionMap : EntityTypeConfiguration<DiscountSchemeAction>
{
public DiscountSchemeActionMap()
{
ToTable("DiscountSchemeAction");
}
}
public class DiscountSchemeMap : EntityTypeConfiguration<DiscountScheme>
{
public DiscountSchemeMap()
{
ToTable("DiscountScheme");
HasRequired(ds => ds.Action);
}
}
我正在尝试进行的查询:
using(var context = new Context()/* My database context, using a custom wrapper framework*/)
{
Console.WriteLine(context.Coupons.ToList()); // nothing
Console.WriteLine(context.DiscountSchemes.ToList()); // the contents of the table
}
如果我查询操作 table,我确实得到了内容,但是对于 CouponAction
我没有得到连接的 Coupon
,对于 DiscountScheme
它按预期工作。
问题出在你们的一对一关系上。默认情况下,EF 期望 1 对 1 在两个 table 上使用 PK。通过将 CouponID 放在 CouponAction 上,您不是在设置 1 对 1 关系,而是在设置 1-to-many/many-to-1。没有什么能阻止多个 CouponAction 记录具有相同的 CouponId。您可以对 CouponID 设置唯一约束,但如果是这种情况,那么您也可以将 CouponAction 的主键设为 CouponID。因此,这就是为什么我不建议使用 "Id" 作为 PK 名称,而是建议使用 CouponId 与 DiscountId 等
如果优惠券和操作之间的关系确实是一对一,那么去掉操作上的 CouponId table,并确保您在两者中使用相同的 ID 值 tables 的相关记录。您可以通过更改映射以将 EF 配置为在 CouponAction 上使用 CouponId 作为 PK 来对此进行测试。执行此操作后,您应该会看到相关记录。
或者,您可以建立从操作到优惠券的多对一关系 (HasOne.WithMany()),但没有 return 优惠券上没有 CouponActionId 的引用。或者您可以设置一对多,其中优惠券包含 ICollection<CouponAction> CouponActions
,即使您打算每张优惠券只执行一个操作。但如果它是 1 对 1,那么我强烈建议在两个 table 中使用相同的 PK 值。
我有两组对象:Coupon
和 DiscountScheme
。
每个都有一个 {Type}Action
的连接对象和相同的配置。
请求 Coupon
时,我没有得到任何回复,
但是 DiscountScheme
的相同查询按预期工作
类 的精简版(table 的完整代码和 sql 可以在 here 中找到):
public class CouponAction
{
public int Id { get; set; }
public virtual Coupon Coupon { get; set; }
}
public class Coupon
{
public int Id { get; set; }
public virtual CouponAction Action { get; set; }
}
public class DiscountSchemeAction
{
public int Id { get; set; }
public virtual DiscountScheme DiscountScheme { get; set; }
}
public class DiscountScheme
{
public int Id { get; set; }
public virtual DiscountSchemeAction Action { get; set; }
}
配置:
public class CouponActionMap : EntityTypeConfiguration<CouponAction>
{
public CouponActionMap()
{
ToTable("CouponAction");
}
}
public class CouponMap : EntityTypeConfiguration<Coupon>
{
public CouponMap()
{
ToTable("Coupon");
HasRequired(c => c.Action);
}
}
public class DiscountSchemeActionMap : EntityTypeConfiguration<DiscountSchemeAction>
{
public DiscountSchemeActionMap()
{
ToTable("DiscountSchemeAction");
}
}
public class DiscountSchemeMap : EntityTypeConfiguration<DiscountScheme>
{
public DiscountSchemeMap()
{
ToTable("DiscountScheme");
HasRequired(ds => ds.Action);
}
}
我正在尝试进行的查询:
using(var context = new Context()/* My database context, using a custom wrapper framework*/)
{
Console.WriteLine(context.Coupons.ToList()); // nothing
Console.WriteLine(context.DiscountSchemes.ToList()); // the contents of the table
}
如果我查询操作 table,我确实得到了内容,但是对于 CouponAction
我没有得到连接的 Coupon
,对于 DiscountScheme
它按预期工作。
问题出在你们的一对一关系上。默认情况下,EF 期望 1 对 1 在两个 table 上使用 PK。通过将 CouponID 放在 CouponAction 上,您不是在设置 1 对 1 关系,而是在设置 1-to-many/many-to-1。没有什么能阻止多个 CouponAction 记录具有相同的 CouponId。您可以对 CouponID 设置唯一约束,但如果是这种情况,那么您也可以将 CouponAction 的主键设为 CouponID。因此,这就是为什么我不建议使用 "Id" 作为 PK 名称,而是建议使用 CouponId 与 DiscountId 等
如果优惠券和操作之间的关系确实是一对一,那么去掉操作上的 CouponId table,并确保您在两者中使用相同的 ID 值 tables 的相关记录。您可以通过更改映射以将 EF 配置为在 CouponAction 上使用 CouponId 作为 PK 来对此进行测试。执行此操作后,您应该会看到相关记录。
或者,您可以建立从操作到优惠券的多对一关系 (HasOne.WithMany()),但没有 return 优惠券上没有 CouponActionId 的引用。或者您可以设置一对多,其中优惠券包含 ICollection<CouponAction> CouponActions
,即使您打算每张优惠券只执行一个操作。但如果它是 1 对 1,那么我强烈建议在两个 table 中使用相同的 PK 值。