Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用Fluent API和代码优先迁移设置外键名?_C#_Vb.net_Entity Framework 6_Entity Framework Migrations_Fluent - Fatal编程技术网

C# 如何使用Fluent API和代码优先迁移设置外键名?

C# 如何使用Fluent API和代码优先迁移设置外键名?,c#,vb.net,entity-framework-6,entity-framework-migrations,fluent,C#,Vb.net,Entity Framework 6,Entity Framework Migrations,Fluent,我正在尝试使用EF6.4上的代码优先迁移设置外键名称(而不是外键列) 我知道可以通过更新生成的迁移代码进行设置,如下所示: .ForeignKey("Documents", Function(t) t.DocumentId, cascadeDelete:=True, name:="FK_Sections_Documents") …但我希望在添加迁移之前,使用Fluent API执行此操作 我似乎还记得关于接受Func调用的HasForeignKey()调用的一些内容,该调用在其主体中包含对匿名

我正在尝试使用EF6.4上的代码优先迁移设置外键名称(而不是外键列)

我知道可以通过更新生成的迁移代码进行设置,如下所示:

.ForeignKey("Documents", Function(t) t.DocumentId, cascadeDelete:=True, name:="FK_Sections_Documents")
…但我希望在添加迁移之前,使用Fluent API执行此操作

我似乎还记得关于接受
Func
调用的
HasForeignKey()
调用的一些内容,该调用在其主体中包含对匿名类型的调用,例如我们找到的。但是,如果我能找到任何讨论这种类型的一般结构应该是什么的东西,那我就倒霉了

官方文件并未对此进行讨论:

这些类似的问答也没有完全解决这个问题:

几个月前也有人问过这个问题,但到目前为止还没有得到答案

我正在使用
EntityTypeConfiguration(Of T)
。这是我的密码:

Namespace Configuration
  Friend Class SectionConfig
    Inherits EntityTypeConfiguration(Of Db.Section)

    Public Sub New()
      Me.HasRequired(Function(Section) Section.Document).WithMany.HasForeignKey(Function(Section) Section.DocumentId)

      Me.Property(Function(Section) Section.DocumentId).IsRequired()
      Me.Property(Function(Section) Section.SectionId).IsRequired()
      Me.Property(Function(Section) Section.IsSent).IsRequired()
      Me.Property(Function(Section) Section.Markup).IsRequired.IsMaxLength()
      Me.Property(Function(Section) Section.Title).IsRequired.HasMaxLength(60)

      Me.HasIndex(Function(Section) Section.DocumentId).HasName("IX_Sections_DocumentId")
      Me.HasIndex(Function(Section) Section.SectionId).HasName("IX_Sections_SectionId")
      Me.HasIndex(Function(Section) Section.Title).HasName("IX_Sections_Title")

      Me.Ignore(Function(Section) Section.Subject)
    End Sub
  End Class
End Namespace
假设我正确地记住了匿名类型的一般结构,那么如何设置外键名,或者更具体地说,如何设置外键名

--更新--

我试过这个:

Me.HasRequired(Function(Section) Section.Document).WithMany.HasForeignKey(Function(Section) New With {.DependentKeyExpression = Section.DocumentId, .Name = "FK_Sections_Documents"})
…但迁移创建尝试的回答如下:

System.Reflection.TargetInvocationException:调用的目标已引发异常。-->System.InvalidOperationException:属性表达式“Section=>new VB$AnonymousType_0`2(DependentKeyExpression=Section.DocumentId,Name=“FK_Sections_Documents”)”无效。表达式应该表示一个属性:C#::“t=>t.MyProperty”VB.Net:“Function(t)t.MyProperty”。指定多个属性时,请使用匿名类型:C#::“t=>new{t.MyProperty1,t.MyProperty2}”VB.Net:“函数(t)new With{t.MyProperty1,t.MyProperty2}”

因此,鉴于匿名类型构造用于指定键列,因此它不是指定外键名称的方法


问题仍然存在:我们如何在EF6.4中使用Fluent API指定外键名?

使用Fluent映射,ForeignKey attibute希望类中有一个属性名作为参数

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
  modelBuilder.Entity<WidgetEntity>()
   .HasRequired(w => w.Sequence)
   .WithMany()
   .Map(m => m.MapKey("FK_Sections_Documents"));
}
名称配置:

HasOptional(p => p.Gender).WithMany(p=>p.Name).HasForeignKey(p=>p.GenderLookupId).WillCascadeOnDelete(false);
如果不想使用流畅的语法,也可以使用,因为反转属性更易于阅读,并且写在它们影响的属性的正上方

更新:

使用具有关联属性的ForeignKey

例1:

例2:


不幸的是,在EF6中没有内置的方法来实现这一点。为了稍微澄清您的问题,您要问的是如何指定基于模型中指定的外键创建的基础数据库约束的名称。这将是迁移生成器的工作。尽管EF6迁移中有传递约束名称的功能,但如果您浏览源代码,您会发现它从未实际使用过,而且所有方法都是私有的和内部的

这已在EFCore中进行了阐述,您现在可以执行以下操作:
Me.HasRequired(函数(节)节.Document).WithMany().HasForeignKey(函数(节)节.DocumentId.HasConstraintName(“FK\U节\U文档”)
但这对您没有帮助


因此,您需要编写一个定制的迁移生成器,它将执行您想要的操作。这篇文章回答了这个确切的问题(C#中的代码,数据库是SQL Server):

几乎可以。从技术上讲,它确实回答了我的问题,所以我已经颁发了赏金,但仍然有一个意想不到的问题
MapKey()
提供了自定义FK名称,是的,但生成的迁移会将具有相同名称的列添加到表中,并将新列用于关系。似乎没有一种方法可以使用
MapKey()
同时指定目标列。哎呀,实际上它不起作用。我授予赏金的时间有点太早了,所以请继续,并用我的赞美来保留它:-)问题是:仔细查看
MapKey()
,结果发现它是用于指定要在键中使用的列,而不是实际的外键名。这与
HasForeignKey()
下的匿名类型方法没有什么不同。命名FK和仅命名FK的方法仍然无法实现。您可以将外键与我的回答中更新的关联属性一起使用,谢谢,但这些是数据注释。不幸的是,使用Fluent API定制外键名似乎是不可能的。这个定制生成器看起来相当不错,尽管我很难让它正常工作。自定义名称不会出现在生成的迁移代码中。不管怎么说,我已经颁发了赏金,因为它很快就要到期了,我不想让你失去它。感谢您找到链接,也感谢您的澄清。我也这么怀疑,你已经证实了。你在使用哪个数据库和数据提供者?我在使用MSSQL。我按照建议把它接线好了。我在
GetFkName()
中插入了一条日志语句,这表明该函数在
Add Migration
期间从未被命中。古怪的
HasOptional(p => p.Gender).WithMany(p=>p.Name).HasForeignKey(p=>p.GenderLookupId).WillCascadeOnDelete(false);
[Table("ENTITIES")]
public class Entity {

    [Column("ENTITY_NO")]
    public int No { set; get; }

    [Column("SEQUENCE_NO")]
    public int SequenceNo { set; get; }

    [ForeignKey("SequenceNo")] //Has to be a property name, not table column name
    public Sequence Sequence { set; get; }

    // and other properties that map correctly
}

[Table("SEQUENCES")]
public class Sequence { 

    [Column("SEQUENCE_NO")]
    public int No { set; get; }

    [Column("NUMBER")]
    public int Number { set; get; }
}
[Table("ENTITIES")]
public class Entity {

    [Column("ENTITY_NO")]
    public int No { set; get; }

    [ForeignKey("Sequence")] //Has to be a property name, not table column name
    [Column("SEQUENCE_NO")]
    public int SequenceNo { set; get; }

    public Sequence Sequence { set; get; }

    // and other properties that map correctly
}

[Table("SEQUENCES")]
public class Sequence { 

    [Column("SEQUENCE_NO")]
    public int No { set; get; }

    [Column("NUMBER")]
    public int Number { set; get; }
}