Entity framework6、非主键列上1到0..1关系的流畅映射
Entity framework 6, fluent mapping of 1 to 0..1 relationship on non-primary-key columns
我正在尝试将 objectcontext/edmx 系统迁移到具有流畅映射的 dbcontext (EF6)。我有几个像下面这样的例子。 Principal table 与 dependent table 有关系,其中 dependent table 中的非 PK 列保存 principal 中 PK 列的值。就其本身而言,这将是一个一对多的关系,但在相关的 table FK 列上有一个唯一索引。使用 EDMX 映射,只要您使用映射而不是引用约束来定义关系,这就可以正常工作。下面是一个 executable 示例 - 您不需要数据库,因为它目前还没有那么远:
Imports System.Data.Entity
Imports System.Data.Entity.ModelConfiguration
Module Module1
Sub Main()
Using session As New SaturnEntities
Dim res = session.BookingLegSet.Select(Function(x) New With {x.Prefix, x.ID, x.AddressDetails.Address}).ToList
End Using
End Sub
End Module
Partial Public Class BookingLeg
Public Property Prefix As String
Public Property ID As Integer
Public Property LegIndex As Integer
Public Overridable Property AddressDetails As BookingLegAddress
End Class
Partial Public Class BookingLegAddress
Public Property Prefix As String
Public Property ID As Integer
Public Property Address As String
Public Overridable Property BookingLeg As BookingLeg
Property JobLegPrefix As String
Property JobLegID As Integer?
End Class
Public Class BookingLegConfig
Inherits EntityTypeConfiguration(Of BookingLeg)
Public Sub New()
ToTable("JobLegs", "dbo")
HasKey(Function(x) New With {x.Prefix, x.ID})
HasOptional(Function(x) x.AddressDetails).WithRequired(Function(x) x.BookingLeg).Map(Function(x) x.MapKey("Prefix", "ID"))
End Sub
End Class
Public Class BookingLegAddressConfig
Inherits EntityTypeConfiguration(Of BookingLegAddress)
Public Sub New()
ToTable("JobAddresses", "dbo")
HasKey(Function(x) New With {x.Prefix, x.ID})
HasRequired(Function(x) x.BookingLeg).WithOptional(Function(x) x.AddressDetails).Map(Function(x) x.MapKey("JobLegPrefix", "JobLegID"))
End Sub
End Class
Partial Public Class SaturnEntities
Inherits DbContext
Public Sub New()
MyBase.New("data source=dbSaturn;initial catalog=Saturn;integrated security=True;MultipleActiveResultSets=True;")
End Sub
Protected Overrides Sub OnModelCreating(modelBuilder As DbModelBuilder)
modelBuilder.Configurations.Add(New BookingLegConfig)
modelBuilder.Configurations.Add(New BookingLegAddressConfig)
End Sub
Public Overridable Property BookingLegAddressSet() As DbSet(Of BookingLegAddress)
Public Overridable Property BookingLegSet() As DbSet(Of BookingLeg)
End Class
BookingLeg 是主体实体,BookingLegAddress 是从属实体。依赖项中的 JobLegPrefix 和 JobLegID 要么为 null,要么将保存 BookingLeg 记录中的 Prefix 和 ID 值。当您 运行 这样做时,您会收到一条错误消息,指出 AddressDetails 配置的映射信息存在冲突。我已经尝试了很多不同的方法来映射它,但没有任何进展 - 谁能告诉我我需要做什么?
删除
HasOptional(Function(x) x.AddressDetails).WithRequired(Function(x) x.BookingLeg).Map(Function(x) x.MapKey("Prefix", "ID"))
来自 BookingLegConfig
class 的行。每个单独的关系只能在一个地方配置一次(两个相关实体中任何一个的配置的一部分,但不能同时在两个实体中配置)。在这种特殊情况下,您应该将第二个配置保留在 BookingLegAddressConfig
class
中
HasRequired(Function(x) x.BookingLeg).WithOptional(Function(x) x.AddressDetails).Map(Function(x) x.MapKey("JobLegPrefix", "JobLegID"))
因为它指定了正确的 FK 列名称。
此外,EF6 不支持针对此类关系的 explicit FK 列 - 没有 HasForeignKey
fluent API,MapKey
适用于指定 shadow 属性(和列)名称。因此,另外从 BookingLegAddress
class:
中删除 JobLegPrefix
和 JobLegID
属性
Partial Public Class BookingLegAddress
Public Property Prefix As String
Public Property ID As Integer
Public Property Address As String
Public Overridable Property BookingLeg As BookingLeg
End Class
我正在尝试将 objectcontext/edmx 系统迁移到具有流畅映射的 dbcontext (EF6)。我有几个像下面这样的例子。 Principal table 与 dependent table 有关系,其中 dependent table 中的非 PK 列保存 principal 中 PK 列的值。就其本身而言,这将是一个一对多的关系,但在相关的 table FK 列上有一个唯一索引。使用 EDMX 映射,只要您使用映射而不是引用约束来定义关系,这就可以正常工作。下面是一个 executable 示例 - 您不需要数据库,因为它目前还没有那么远:
Imports System.Data.Entity
Imports System.Data.Entity.ModelConfiguration
Module Module1
Sub Main()
Using session As New SaturnEntities
Dim res = session.BookingLegSet.Select(Function(x) New With {x.Prefix, x.ID, x.AddressDetails.Address}).ToList
End Using
End Sub
End Module
Partial Public Class BookingLeg
Public Property Prefix As String
Public Property ID As Integer
Public Property LegIndex As Integer
Public Overridable Property AddressDetails As BookingLegAddress
End Class
Partial Public Class BookingLegAddress
Public Property Prefix As String
Public Property ID As Integer
Public Property Address As String
Public Overridable Property BookingLeg As BookingLeg
Property JobLegPrefix As String
Property JobLegID As Integer?
End Class
Public Class BookingLegConfig
Inherits EntityTypeConfiguration(Of BookingLeg)
Public Sub New()
ToTable("JobLegs", "dbo")
HasKey(Function(x) New With {x.Prefix, x.ID})
HasOptional(Function(x) x.AddressDetails).WithRequired(Function(x) x.BookingLeg).Map(Function(x) x.MapKey("Prefix", "ID"))
End Sub
End Class
Public Class BookingLegAddressConfig
Inherits EntityTypeConfiguration(Of BookingLegAddress)
Public Sub New()
ToTable("JobAddresses", "dbo")
HasKey(Function(x) New With {x.Prefix, x.ID})
HasRequired(Function(x) x.BookingLeg).WithOptional(Function(x) x.AddressDetails).Map(Function(x) x.MapKey("JobLegPrefix", "JobLegID"))
End Sub
End Class
Partial Public Class SaturnEntities
Inherits DbContext
Public Sub New()
MyBase.New("data source=dbSaturn;initial catalog=Saturn;integrated security=True;MultipleActiveResultSets=True;")
End Sub
Protected Overrides Sub OnModelCreating(modelBuilder As DbModelBuilder)
modelBuilder.Configurations.Add(New BookingLegConfig)
modelBuilder.Configurations.Add(New BookingLegAddressConfig)
End Sub
Public Overridable Property BookingLegAddressSet() As DbSet(Of BookingLegAddress)
Public Overridable Property BookingLegSet() As DbSet(Of BookingLeg)
End Class
BookingLeg 是主体实体,BookingLegAddress 是从属实体。依赖项中的 JobLegPrefix 和 JobLegID 要么为 null,要么将保存 BookingLeg 记录中的 Prefix 和 ID 值。当您 运行 这样做时,您会收到一条错误消息,指出 AddressDetails 配置的映射信息存在冲突。我已经尝试了很多不同的方法来映射它,但没有任何进展 - 谁能告诉我我需要做什么?
删除
HasOptional(Function(x) x.AddressDetails).WithRequired(Function(x) x.BookingLeg).Map(Function(x) x.MapKey("Prefix", "ID"))
来自 BookingLegConfig
class 的行。每个单独的关系只能在一个地方配置一次(两个相关实体中任何一个的配置的一部分,但不能同时在两个实体中配置)。在这种特殊情况下,您应该将第二个配置保留在 BookingLegAddressConfig
class
HasRequired(Function(x) x.BookingLeg).WithOptional(Function(x) x.AddressDetails).Map(Function(x) x.MapKey("JobLegPrefix", "JobLegID"))
因为它指定了正确的 FK 列名称。
此外,EF6 不支持针对此类关系的 explicit FK 列 - 没有 HasForeignKey
fluent API,MapKey
适用于指定 shadow 属性(和列)名称。因此,另外从 BookingLegAddress
class:
JobLegPrefix
和 JobLegID
属性
Partial Public Class BookingLegAddress
Public Property Prefix As String
Public Property ID As Integer
Public Property Address As String
Public Overridable Property BookingLeg As BookingLeg
End Class