C# 首先使用EF代码映射复合键
Sql server表:C# 首先使用EF代码映射复合键,c#,sql-server,entity-framework,entity-framework-6,C#,Sql Server,Entity Framework,Entity Framework 6,Sql server表: SomeId PK varchar(50) not null OtherId PK int not null 我应该如何在EF 6代码中首先映射它 public class MyTable { [Key] public string SomeId { get; set; } [Key] public int OtherId { get; set; } } 我见过一些例子,你必须为每一列设置顺序,这是必需的吗 有关于这方面的官方文档
SomeId PK varchar(50) not null
OtherId PK int not null
我应该如何在EF 6代码中首先映射它
public class MyTable
{
[Key]
public string SomeId { get; set; }
[Key]
public int OtherId { get; set; }
}
我见过一些例子,你必须为每一列设置顺序,这是必需的吗
有关于这方面的官方文档吗?您肯定需要按列顺序排列,否则SQL Server怎么知道哪一个先到?以下是您需要在代码中执行的操作:
public class MyTable
{
[Key, Column(Order = 0)]
public string SomeId { get; set; }
[Key, Column(Order = 1)]
public int OtherId { get; set; }
}
你也可以看看。如果你想要官方文件,我建议你看看。希望这有帮助
编辑:我刚找到朱莉·勒曼的一篇博文,上面有各种EF 6善良的链接。您可以找到您需要的任何东西。通过配置,您可以执行以下操作:
Model1
{
int fk_one,
int fk_two
}
Model2
{
int pk_one,
int pk_two,
}
然后在上下文配置中
public class MyContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Model1>()
.HasRequired(e => e.Model2)
.WithMany(e => e.Model1s)
.HasForeignKey(e => new { e.fk_one, e.fk_two })
.WillCascadeOnDelete(false);
}
}
公共类MyContext:DbContext
{
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Entity()
.HasRequired(e=>e.Model2)
.WithMany(e=>e.Model1s)
.HasForeignKey(e=>new{e.fk_one,e.fk_two})
.WillCascadeOnDelete(假);
}
}
对于使用实体框架映射复合主键,我们可以使用两种方法
1) 通过重写OnModelCreating()方法
例如:我有一个名为VehicleFeature的模型类,如下所示
public class VehicleFeature
{
public int VehicleId { get; set; }
public int FeatureId{get;set;}
public Vehicle Vehicle{get;set;}
public Feature Feature{get;set;}
}
DBContext中的代码如下:
public class VegaDbContext : DbContext
{
public DbSet<Make> Makes{get;set;}
public DbSet<Feature> Features{get;set;}
public VegaDbContext(DbContextOptions<VegaDbContext> options):base(options)
{
}
// we override the OnModelCreating method here.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<VehicleFeature>().HasKey(vf=> new {vf.VehicleId, vf.FeatureId});
}
}
有关更多信息,请参阅以下链接
(一)
2) 我想我会补充这个问题,因为它是谷歌搜索结果中最热门的 如评论中所述,在EF Core中不支持使用注释(键属性),必须使用fluent完成 当我正在进行从EF6到EF Core的大规模迁移时,这是不令人满意的,因此我尝试通过使用反射来查找键属性,然后在onmodel创建期间应用它
// get all composite keys (entity decorated by more than 1 [Key] attribute
foreach (var entity in modelBuilder.Model.GetEntityTypes()
.Where(t =>
t.ClrType.GetProperties()
.Count(p => p.CustomAttributes.Any(a => a.AttributeType == typeof(KeyAttribute))) > 1))
{
// get the keys in the appropriate order
var orderedKeys = entity.ClrType
.GetProperties()
.Where(p => p.CustomAttributes.Any(a => a.AttributeType == typeof(KeyAttribute)))
.OrderBy(p =>
p.CustomAttributes.Single(x => x.AttributeType == typeof(ColumnAttribute))?
.NamedArguments?.Single(y => y.MemberName == nameof(ColumnAttribute.Order))
.TypedValue.Value ?? 0)
.Select(x => x.Name)
.ToArray();
// apply the keys to the model builder
modelBuilder.Entity(entity.ClrType).HasKey(orderedKeys);
}
我还没有在所有情况下完全测试过它,但它在我的基本测试中都有效。希望这有助于某人是
SomeId
字符串还是int
?@IronMan84这是一个字符串,我会解决它。如何通过EntityConfiguration实现这一点?我实际上没有连接表的实体。。。我只有两个实体,其中一个实体上有一个EntityConfiguration,上面有一个.Map()来设置映射。否则SQL Server怎么知道哪一个先到?
-为什么它不知道其他列的顺序?EF不知道其他列的顺序,只要指定了名称,就可以按任意顺序插入with列。如果EF需要复合PK的顺序,那么它必须与索引相关。@Davor我想EF创建者可以使用反射来推断键/列顺序,但不这样做可能会有性能方面的考虑。我会在任何一天,特别是在我的DAL中,考虑到设计时间的特殊性,而不是较慢的性能。我认为提前订购是有意义的。如果有一天你对这些属性重新排序,你会发现实体框架停止工作,你会非常生气。在上下文配置中的什么地方?如果你是通过使用Fluent API的代码配置上下文。公共类MyContext:DbContext{protected override void OnModelCreating(DbModelBuilder modelBuilder){modelBuilder.Entity().HasRequired(e=>e.Model2)。带有多个(e=>e.Model1s)。HasForeignKey(e=>new{e.fk_one,e.fk_two})。WillCascadeOnDelete(false);}}我发现我必须在dotnet core.FYI上使用ModelBuilder而不是DbModelBuilder。对于EF core,选项#2是,“只能使用流畅的API配置组合键-约定永远不会设置组合键,并且不能使用数据注释来配置组合键。”
// get all composite keys (entity decorated by more than 1 [Key] attribute
foreach (var entity in modelBuilder.Model.GetEntityTypes()
.Where(t =>
t.ClrType.GetProperties()
.Count(p => p.CustomAttributes.Any(a => a.AttributeType == typeof(KeyAttribute))) > 1))
{
// get the keys in the appropriate order
var orderedKeys = entity.ClrType
.GetProperties()
.Where(p => p.CustomAttributes.Any(a => a.AttributeType == typeof(KeyAttribute)))
.OrderBy(p =>
p.CustomAttributes.Single(x => x.AttributeType == typeof(ColumnAttribute))?
.NamedArguments?.Single(y => y.MemberName == nameof(ColumnAttribute.Order))
.TypedValue.Value ?? 0)
.Select(x => x.Name)
.ToArray();
// apply the keys to the model builder
modelBuilder.Entity(entity.ClrType).HasKey(orderedKeys);
}