Entity-Framework 6,通过两个 ID 定义关系
Entity-Framework 6, defining relationship by two IDs
上下文:我必须将模型的一部分从单个值更改为条目列表,并且需要帮助定义两者之间的关系 类。
模型 (简化) 看起来像这样:
public class Settings {
public Guid Id { get; set; }
public Guid NodeId { get; set; }
public Guid UserId { get; set; }
public Guid TemplateId { get; set; }
// plus the respective virtual properties and a few more irrelevant things.
}
现在关系已经改变,所以我必须处理多个模板,加上一些新标志,变成这样:
public class Settings {
public Guid Id { get; set; }
public Guid NodeId { get; set; }
public Guid UserId { get; set; }
public ICollection<TemplateConfig> Configs { get; set; }
// ...
}
public class TemplateConfig {
public Guid NodeId { get; set; }
public Guid UserId { get; set; }
public Guid TemplateId { get; set; }
// and a few more flags
}
builder.Entity<TemplateConfig>().HasKey(t => new { t.NodeId, t.UserId, t.TemplateId });
由于我的许多访问将直接在此列表上并且基于节点、用户或模板的所有条目,所以我不介意 ID 中的冗余,实际上我更喜欢它。
我想不必须添加一个SettingsId
才能定义这种关系,而是做这样的事情:
builder.Entity<Settings>()
.HasMany(s => s.Configs)
.HasForeignKey(s => new {s.NodeId, s.UserId});
因此基于共享 ID 对 NodeId, UserId
。
但是我对EF的了解还是很有限
我已经通过 DbModelBuilder
以及 ForeignKey
和 Column
属性进行了尝试。不同的错误;所有归结为关系中委托人和依赖者之间的 ID 数量不匹配。
感谢您的帮助。
您 Settings
class 有一个单列主键 public Guid Id { get; set; }
。当您定义关系时,EF 核心会尝试将 2 列外键 .HasForeignKey(s => new {s.NodeId, s.UserId});
绑定到 'Settings'
的 1 列主键,这是不可能的。但是您可以告诉 EF 将外键绑定到称为“主键”的不同列。尝试像这样在您的代码中添加 .WithPrincipal()
:
builder.Entity<Settings>()
.HasMany(s => s.Configs)
.WithOne()
.HasForeignKey(c => new {c.NodeId, c.UserId})
.HasPrincipalKey(s => new {s.NodeId, s.UserId});
EF 6 的答案:
由于 EF 6 没有 .HasPrincipalKey()
,因此应使用 .Map()
:
指定主列
builder.Entity<Settings>()
.HasMany(s => s.Configs)
.WithOne()
.Map(cs =>
{
cs.MapLeftKey("NodeId", "UserId");
cs.MapRightKey("NodeId", "UserId");
});
上下文:我必须将模型的一部分从单个值更改为条目列表,并且需要帮助定义两者之间的关系 类。
模型 (简化) 看起来像这样:
public class Settings {
public Guid Id { get; set; }
public Guid NodeId { get; set; }
public Guid UserId { get; set; }
public Guid TemplateId { get; set; }
// plus the respective virtual properties and a few more irrelevant things.
}
现在关系已经改变,所以我必须处理多个模板,加上一些新标志,变成这样:
public class Settings {
public Guid Id { get; set; }
public Guid NodeId { get; set; }
public Guid UserId { get; set; }
public ICollection<TemplateConfig> Configs { get; set; }
// ...
}
public class TemplateConfig {
public Guid NodeId { get; set; }
public Guid UserId { get; set; }
public Guid TemplateId { get; set; }
// and a few more flags
}
builder.Entity<TemplateConfig>().HasKey(t => new { t.NodeId, t.UserId, t.TemplateId });
由于我的许多访问将直接在此列表上并且基于节点、用户或模板的所有条目,所以我不介意 ID 中的冗余,实际上我更喜欢它。
我想不必须添加一个SettingsId
才能定义这种关系,而是做这样的事情:
builder.Entity<Settings>()
.HasMany(s => s.Configs)
.HasForeignKey(s => new {s.NodeId, s.UserId});
因此基于共享 ID 对 NodeId, UserId
。
但是我对EF的了解还是很有限
我已经通过 DbModelBuilder
以及 ForeignKey
和 Column
属性进行了尝试。不同的错误;所有归结为关系中委托人和依赖者之间的 ID 数量不匹配。
感谢您的帮助。
您 Settings
class 有一个单列主键 public Guid Id { get; set; }
。当您定义关系时,EF 核心会尝试将 2 列外键 .HasForeignKey(s => new {s.NodeId, s.UserId});
绑定到 'Settings'
的 1 列主键,这是不可能的。但是您可以告诉 EF 将外键绑定到称为“主键”的不同列。尝试像这样在您的代码中添加 .WithPrincipal()
:
builder.Entity<Settings>()
.HasMany(s => s.Configs)
.WithOne()
.HasForeignKey(c => new {c.NodeId, c.UserId})
.HasPrincipalKey(s => new {s.NodeId, s.UserId});
EF 6 的答案:
由于 EF 6 没有 .HasPrincipalKey()
,因此应使用 .Map()
:
builder.Entity<Settings>()
.HasMany(s => s.Configs)
.WithOne()
.Map(cs =>
{
cs.MapLeftKey("NodeId", "UserId");
cs.MapRightKey("NodeId", "UserId");
});