【问题标题】:Entity Framework 1-1 relationship is not persisting data to the database实体框架 1-1 关系未将数据持久化到数据库
【发布时间】:2012-12-21 19:12:43
【问题描述】:

我有一张桌子 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 没有。

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

【问题讨论】:

  • 您能否向我们展示您基于这些类创建和持久化这些对象的代码?

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


【解决方案1】:

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

         Public Overridable Property MetaData As FeeMetadata

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

VB.NET Overridable Keyword

DatabaseGenerated 属性

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

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

属性

您还拥有作为 Key 和 ForeignKey 列出的相同属性 (FeeID)。

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

就我个人而言,我会将 Metadata 类更改为类似的内容,并根据需要效仿其他类:

<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 来描述返回元数据的导航。

【讨论】:

  • 为什么不使用 Overridable 关键字,PFD.Fee 实体也能工作?
  • 另外,overridable 关键字允许在派生类中覆盖该属性。这里没有派生类。你能指出一些建立这种联系的 ef 文档吗?
  • 另外,我尝试了您的建议,并获得了与以前相同的结果。可覆盖似乎没有任何区别。
  • 目前无法访问开发环境,但这对我来说很重要。我现在主要使用 C# 工作,并且 EF 导航属性被声明为虚拟(相当于 VB.NET 中的可覆盖),以便延迟加载工作。因此,我一直在自动声明我的属性,并且暂时没有考虑为什么。我稍后会更新我的答案。
  • 我从 SoaCourt.FeePFD.Fee 类中删除了 DatabaseGenerated 属性。结果相同:PFD.FeeMetadataPFD.Fees 表被填充,SoaCourt.Fees 没有得到任何记录。
【解决方案2】:

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

总而言之:EF5 不能持久化来自不同命名空间的同名类。 实体类名称在命名空间中必须是唯一的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-11
    • 1970-01-01
    相关资源
    最近更新 更多