实体框架1-1关系不是将数据持久保存到数据库

时间:2012-12-21 19:12:43

标签: vb.net entity-framework ef-code-first entity-framework-5

我有一张表FeeMetadata,其中包含PK FeeID BIGINT IDENTITY(1,1) NOT NULL

此表包含两个1-1关系。一个到PFD.Fees,一个到SoaCourt.Fees通过FeeID列(在所有三个表中同名,只有元数据表被标记为IDENTITY,另外两个表这个列是PK但是不是身份)

以下是EF课程的代码:

Namespace PFD

    <Table("FeeMetadata", Schema:="PFD")>
    Public Class FeeMetadata
        Public Sub New()
            MyBase.New()
        End Sub

        Public Sub New(ByVal tFee As SOACourt_v1)
            Me.New()

            Me.GroupKey = tFee.DriverLicenseNumber
            Me.PfdFee = New PFD.Fee(tFee)
            Me.SoaCourtFee = New SoaCourt.Fee(tFee)
        End Sub

        <Key>
        <DatabaseGenerated(DatabaseGeneratedOption.Identity)>
        Public Property FeeID As Int64

        ' Other domain-specific properties...

        Public Property SoaCourtFee As SoaCourt.Fee
    End Class
End Namespace


Namespace PFD
    <Table("Fees", Schema:="PFD")>
    Public Class Fee
        Public Sub New()
            MyBase.New()
        End Sub

        Public Sub New(ByVal tFee As SOACourt_v1)
            Me.New()

            Me.Amount = tFee.Amount
        Me.DueDate = tFee.DueDate
        End Sub

        <Key>
        <ForeignKey("MetaData")>
        <DatabaseGenerated(DatabaseGeneratedOption.None)>
        Public Property FeeID As Int64

        ' Other domain-specific properties...

        Public Property MetaData As FeeMetadata
    End Class
End Namespace


Namespace SoaCourt
    <Table("Fees", Schema:="SoaCourt")>
    Public Class Fee
        Public Sub New()
            MyBase.New()
        End Sub

        Public Sub New(ByVal tFee As SOACourt_v1)
            Me.New()

            Me.CaseID = tFee.CaseID
            Me.CaseNumber = tFee.CaseNumber
            Me.TicketNumber = tFee.TicketNumber
        End Sub

        <Key>
        <ForeignKey("MetaData")>
        <DatabaseGenerated(DatabaseGeneratedOption.None)>
        Public Property FeeID As Int64

        ' Other domain-specific properties 

        Public Property MetaData As PFD.FeeMetadata
    End Class
End Namespace

编辑: 用于创建和保留数据库实体的代码:

Using tContext As FeesContext = New FeesContext
    For Each tFee As SOACourt_v1 In tFees
        tContext.FeeMetadata.Add(New PFD.FeeMetadata(tFee))
    Next
    tContext.SaveChanges()
End Using

我遇到的问题是SoaCourt.Fee实体没有被持久化到数据库。 PFD.FeeMetadata和PFD.Fee都正常保存,但SoaCourt.Fee不是。

关于如何解决这个问题的任何想法?

2 个答案:

答案 0 :(得分:0)

我相信您需要在VB.NET中将这些导航属性标记为Overridable

         Public Overridable Property MetaData As FeeMetadata

这允许在EntityFramework使用时覆盖属性,否则它会将其视为本地(未映射)属性。

VB.NET Overridable Keyword

DatabaseGenerated属性

以上是错误的。 virtual(C#)和Overridable(VB.NET)用于允许延迟加载关联实体。

由于<DatabaseGenerated(DatabaseGeneratedOption.None)>属性,它是否有可能做一些有趣的事情?您不应该在外键属性上需要它。 EF将自己处理外键的分配,并且因为您指定它不是数据库生成的,所以它期望您显式分配值?

属性

您还将相同的属性(FeeID)列为Key和ForeignKey。

FeeID应该仍然是一个关键,你应该有一个标记为ForeignKey的MetadataID的第二个属性。即使您可能希望将所有关联记录设置为具有相同的键值(如果有效,您的帖子中的代码将完成),很可能在某些时候您需要这样的重新关联方式这些对象。最好从一开始就设计它。

就个人而言,我会将元数据类更改为类似的内容,并根据需要跟随其他类:

<Table("FeeMetadata", Schema:="PFD")>
Public Class FeeMetadata
    Public Sub New()
        MyBase.New()
    End Sub

    Public Sub New(ByVal tFee As SOACourt_v1)
        Me.New()

        Me.GroupKey = tFee.DriverLicenseNumber
        Me.PfdFee = New PFD.Fee(tFee)
        Me.SoaCourtFee = New SoaCourt.Fee(tFee)
    End Sub

    <Key>
    Public Property FeeMetadataID as Int64

    Public Property SoaFeeID As Int64
    Public Property PfdFeeID As Int64

    <ForeignKey("SoaFeeID")>
    Public Property SoaCourtFee As SoaCourt.Fee
    <ForeignKey("PfdFeeID")>
    Public Property PfdFee As PFD.Fee
End Class

这表示一个包含三个字段的表:一个主键(FeeMetadataID)和两个外键(SoaCourtFeeID和PfdFeeID)。导航属性使用属性中的外键值来创建关系。除了属性声明本身之外,这些导航属性的另一端实际上没有必要。在这种情况下,甚至不是外键属性,我很确定。所以SOACourt.Fee可以简单地是Key属性,无论你想要什么数据属性,还有一个简单的Public Overridable Property Metadata as FeeMetadata来描述导航回元数据。

答案 1 :(得分:0)

this question的答案就是解决方案。

总结:EF5不能从不同的名称空间中持久保存同名的类。 实体类名称在名称空间中必须是唯一的。