对我来说,这听起来像是您需要一个额外的实体来连接,Period
我们称之为。该实体 - 以及相应的表 - 将具有三个外键和三个引用(并且没有集合)。我会将该实体的主键设为三个外键的组合,因为我猜该组合必须是唯一的。它看起来像这样(以 Code-First 风格):Client
Activity
ClientActivityInPeriod
public class ClientActivityInPeriod
{
[Key, ForeignKey("Period"), Column(Order = 1)]
public int PeriodId { get; set; }
[Key, ForeignKey("Client"), Column(Order = 2)]
public int ClientId { get; set; }
[Key, ForeignKey("Activity"), Column(Order = 3)]
public int ActivityId { get; set; }
public Period Period { get; set; }
public Client Client { get; set; }
public Activity Activity { get; set; }
}
所有三个外键都是必需的(因为属性不可为空)。
Period
,Client
并且Activity
可以有引用该实体的集合(但它们不需要),例如Period
:
public class Period
{
[Key]
public int PeriodId { get; set; }
public ICollection<ClientActivityInPeriod> ClientActivities { get; set; }
}
您不能拥有像Clients
in集合这样的导航属性Period
,其中包含在给定期间内有任何活动的所有客户端,因为它需要具有 from Client
to的外键或andPeriod
之间的多对多链接表。只有当客户端有活动时,才会填充外键或链接表。EF 和数据库都不会帮助您处理这样的业务逻辑。您必须对此进行编程,并确保在该期间添加或删除活动时正确更新关系 - 这容易出错并且存在数据一致性风险。Client
Period
Period
相反,您将通过查询而不是导航属性获取在给定时间段内有活动的客户端,1
例如:
var clientsWithActivitiesInPeriod1 = context.Periods
.Where(p => p.PeriodId == 1)
.SelectMany(p => p.ClientActivities.Select(ca => ca.Client))
.Distinct()
.ToList();