4

Any suggestions on how I can double-map this parent-child relationship, where the parent has a normal 1-many relationship (which is working), but then I need a direct 1:1,0 link from the parent to a particular child.

Public Class Source
    <Key()>
    Public Property SourceID As Int32

    Public Property SourceFields As List(Of SourceField)

    Public Property InboundMatchKeySourceFieldID As Nullable(Of Int32)
    Public Property InboundMatchKeySourceField As SourceField

And

Public Class SourceField
    <Key()>
    Public Property SourceFieldID As Int32

    Public Property SourceID As Int32

    Public Property Source As Source

This is the Parent/Child Mapping (Working)

    modelBuilder.Entity(Of Source).HasMany(
        Function(S) S.SourceFields
    ).WithRequired(
        Function(SF) SF.Source
    ).HasForeignKey(
        Function(SF) SF.SourceID
    )

This is my failed attempt at an additional direct mapping (Not Working):

modelBuilder.Entity(Of Source
    ).HasOptional(
        Function(S) S.InboundMatchKeySourceField
    ).WithRequired(
        Function(SF) SF.Source
    )

This yields me the 'MetaDataException':

Schema specified is not valid. Errors: The relationship '_____.Source_InboundMatchKeySourceField' was not loaded because the type '_____.SourceField' is not available.

Tom Halladay
  • 5,651
  • 6
  • 46
  • 65

2 Answers2

0

.WithRequired(...) returns a instance of ForeignKeyNavigationPropertyConfiguration. You need to map this relationship to a Key using the map Method, otherwise EF will try to create one for you.

so the code you are looking for is:

modelBuilder.Entity(Of Source
).HasOptional(
    Function(S) S.InboundMatchKeySourceField
).WithRequired(
    Function(SF) SF.Source
) _
.Map(Function (x) x.MapKey("InboundMatchKeySourceFieldID"))
Chad Carisch
  • 2,422
  • 3
  • 22
  • 30
0

You can't use the same property SourceField.Source for both relationships.

There's ambiguity from Entity Framework's perspective:

  • If you set someSourceField.Source, does that mean someSourceField gets added to thatSource.SourceFields, or thatSource.InboundMatchKeySourceField gets set, or both?
  • What if someSource.InboundMatchKeySourceField.Source != someSource?

Perhaps you could create the second mapping without a navigation property and use validation to make sure SourceFields.Contains(InboundMatchKeySourceField) or thisSource.InboundMatchKeySourceField.Source == thisSource if needed:

modelBuilder.Entity(Of Source
    ).HasOptional(
        Function(S) S.InboundMatchKeySourceField
    ).WithRequired()
jjj
  • 4,822
  • 1
  • 16
  • 39