我知道有很多关于这个问题的问题,但经过几天思考后,我仍然无法弄清楚如何让它发挥作用。
我正在编写一个自动校准设备的应用程序。
我有2个表Transmitter
和Calibration
。
Transmitter
可以有零个,一个或多个Calibration
,Calibration
必须属于发射器。
现在Transmitter
应该有一个OfficialCalibration
,可以为空,例如在没有校准的情况下。
所以我想在没有joiner表的情况下实现这个,只需在Transmitter
中使用OfficialCalibrationId。 (两种方式我都需要更新2个表,但所以我的表总数更少)。
将此关系作为navigationProperty也很好,所以我可以调用Transmitter.OfficialCalibration
并获得正确的Calibration
。
因此,如果没有"加入" -Table在EF Code First中,可以做到这一点?
我尝试使用一对多关系和一个附加约束来定义一对一的方法,但这样我有两个问题
Tranmitters
,我不想要现在我试过了:
modelBuilder.Entity(of Transmitter)
.HasMany(Function(c)c.Calibrations)
.WithRequired(Function(t)t.Transmitter)
.HasForeignKey(Function(t)t.TransmitterId)
但是仍然存在下图中显示的一对一关系的问题。
关系是Transmitter.Id
- > Calibration.Id
但应该是Transmitter.OfficialCalibrationId
- > Calibration.Id
通过这种方式,我无法强制校准为OfficialCalibration
只有一个Transmitter
对吗?我可以用某种方式强行吗?我只能考虑使用包含Transmitter_DefaultCalbration
和TransmitterId
列的加入表CalibrationId
并使TransmitterId
成为主键?
我仍在学习使用EF进行复杂的场景,所以任何信息或指导都会很好。
答案 0 :(得分:1)
发射器 - 校准关系是1-n关系,因此您不需要连接表。
如您所知,您可以通过2种方式指定OfficialCalibration,在Transmitter(Transmitter.OfficialCalibration)上插入属性或在Calibration(Calibration.Default)中插入标记。两个关系都需要用代码强制执行,因为:
- 如果插入属性,则无法确定OfficialCalibration是与变送器相关的校准之一;
- 如果您插入标记,则无法确定只有一个正式校准。在写作时思考,可能这可以使用唯一索引来强制执行。
其他答案:
- 通常,您不需要导航属性来定义关系(您只需要2个导航属性中的一个);
如果您不想要Calibrations属性,那么这就是C#中的模型
class Context : DbContext
{
public DbSet<Transmitter> Transmitters { get; set; }
public DbSet<Calibration> Calibrations { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Calibration>()
.HasRequired(_ => _.Transmitter);
}
}
class Calibration
{
public int Id { get; set; }
[MaxLength(50)]
public string Description { get; set; }
public virtual Transmitter Transmitter { get; set; }
}
class Transmitter
{
public int Id { get; set; }
[MaxLength(50)]
public string Description { get; set; }
public virtual Calibration OfficialCalibration { get; set; }
}
如果您首选默认属性,我将实现此模型(在这种情况下,我更喜欢具有Calibrations导航属性)
class Context : DbContext
{
public DbSet<Transmitter> Transmitters { get; set; }
public DbSet<Calibration> Calibrations { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Transmitter>()
.HasMany(_ => _.Calibrations)
.WithRequired(_ => _.Transmitter);
}
}
class Calibration
{
public int Id { get; set; }
[MaxLength(50)]
public string Description { get; set; }
public bool? Default { get; set; }
public virtual Transmitter Transmitter { get; set; }
}
class Transmitter
{
public int Id { get; set; }
[MaxLength(50)]
public string Description { get; set; }
public virtual ICollection<Calibration> Calibrations { get; set; }
public Calibration GetOfficialCalibration()
{
// This could trigger lazy load
return Calibrations.FirstOrDefault(_ => _.Default == true);
}
}