我正在尝试通过流畅的映射将objectcontext / edmx系统迁移到dbcontext(EF6)。我有一些类似以下的例子。主体表与从属表有关系,其中从属表中的非PK列保存了主体中PK列的值。它本身将是一对多的关系,但是从属表FK列上有唯一索引。使用EDMX映射,只要您使用映射而不是引用约束定义关系,此方法就可以正常工作。下面是一个可执行的示例-您不需要数据库,因为当前数据库还不算远。
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已配置有冲突的映射信息。我尝试了许多不同的方法来对此进行映射,但是却一无所获-有人可以告诉我我需要做什么吗?
答案 0 :(得分:2)
删除
HasOptional(Function(x) x.AddressDetails).WithRequired(Function(x) x.BookingLeg).Map(Function(x) x.MapKey("Prefix", "ID"))
BookingLegConfig
类的行。每个单一关系只能在一个位置配置一次(这是两个涉及实体中任何一个的配置的一部分,但不能同时配置)。在这种情况下,您应该将第二个配置保留在BookingLegAddressConfig
类中
HasRequired(Function(x) x.BookingLeg).WithOptional(Function(x) x.AddressDetails).Map(Function(x) x.MapKey("JobLegPrefix", "JobLegID"))
因为它指定了正确的FK列名称。
对于这种类型的关系,EF6也不支持显式 FK列-没有HasForeignKey
流利的API,而MapKey
用于指定阴影属性(和列)名称。因此,请另外从JobLegPrefix
类中删除JobLegID
和BookingLegAddress
属性:
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