Entity Framework 1-1 relationship is not persisting data to the database

别来无恙 提交于 2019-12-13 16:27:26

问题


I've got a table FeeMetadata with a PK FeeID BIGINT IDENTITY(1,1) NOT NULL

This table contains two 1-1 relationships. One to PFD.Fees, and one to SoaCourt.Fees via the FeeID column (same name in all three tables, only the metadata table is marked as IDENTITY, the other two tables this column is PK but NOT identity)

Here's the code for the EF classes:

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

EDIT: Code to create and persist the database entities:

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

The problem I am having is that the SoaCourt.Fee entities are not being persisted to the database. PFD.FeeMetadata and PFD.Fee are both saving properly, but SoaCourt.Fee is NOT.

Any thoughts on how to solve this?


回答1:


I believe you need to mark those navigation properties as Overridable in VB.NET

         Public Overridable Property MetaData As FeeMetadata

This allows the property to be overridden when used by EntityFramework, otherwise it will treat it as a local (unmapped) property.

VB.NET Overridable Keyword

DatabaseGenerated attribute

The above is erroneous. virtual (C#) and Overridable (VB.NET) are used to allow for lazy loading of associated entities.

Is it possible that it is doing something funny because of the <DatabaseGenerated(DatabaseGeneratedOption.None)> attribute? You should not need that on a foreign key property. EF will handle the assignment of foreign keys by itself, and because you are specifying that it is not Database Generated, it is expecting you to explicitly assign a value?

Properties

You also have the same property (FeeID) listed as a Key and a ForeignKey.

FeeID should remain a key, and you should have a second property for MetadataID marked as the ForeignKey. Even though you likely want to have all of your associated records to have the same key value (which the code in your post would accomplish if it worked) it is quite likely that at some point you are going to need so way of re-associating these objects. Better to design it from the beginning.

Personally I would change the Metadata class to something like this and follow suit on the others as needed:

<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

This represents a table with three fields: one primary key (FeeMetadataID) and two foreign keys (SoaCourtFeeID and PfdFeeID). The navigation properties use the foreign key values in the attributes to create the relationship. Nothing is actually necessary on the other end of these navigation properties besides the property declaration itself. In this case, not even a foreign key attribute, I am pretty sure. So SOACourt.Fee could simply be the Key property, whatever data properties you want, and a simple Public Overridable Property Metadata as FeeMetadata to describe the navigation back to the metadata.




回答2:


The answer to this question is the solution here.

In summary: EF5 can not persist classes of the same name from different namespaces. Entity class names must be unique across namespaces.



来源:https://stackoverflow.com/questions/13995858/entity-framework-1-1-relationship-is-not-persisting-data-to-the-database

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!