Search code examples
entity-frameworkasp.net-web-apiodatajaydata

Two distinct associations instead of one


I have two related entities (I've added all possible data annotations, but it seems that ODataConventionModelBuilder ignores them):

public class Examination
{
    [InverseProperty("Examination")]
    public virtual ICollection<Variable> Variables { get; set; }
}

public abstract class Variable
{
    [Required]
    public int? ExaminationId { get; set; }

    [Required]
    [ForeignKey("ExaminationId")]
    [InverseProperty("Variables")]
    public virtual Examination Examination { get; set; }
}

Here is an OData model generation (it seems, that HasMany() and HasRequired() doesn't affect resulting model):

        var modelBuilder = new ODataConventionModelBuilder();
        modelBuilder.EntitySet<Examination>("Examinations");
        modelBuilder.EntitySet<Variable>("Variables");

        modelBuilder.Entity<Examination>().HasMany(e => e.Variables);
        modelBuilder.Entity<Variable>().HasRequired(v => v.Examination);

        return modelBuilder.GetEdmModel();

Resulting model:

<EntityType Name="Examination">
  <NavigationProperty Name="Variables" Relationship="YoStat.Models.YoStat_Models_Examination_Variables_YoStat_Models_Variable_VariablesPartner" ToRole="Variables" FromRole="VariablesPartner"/>
</EntityType>
<EntityType Name="Variable" Abstract="true">
  <NavigationProperty Name="Examination" Relationship="YoStat.Models.YoStat_Models_Variable_Examination_YoStat_Models_Examination_ExaminationPartner" ToRole="Examination" FromRole="ExaminationPartner"/>
</EntityType>

<Association Name="YoStat_Models_Examination_Variables_YoStat_Models_Variable_VariablesPartner">
  <End Type="YoStat.Models.Variable" Role="Variables" Multiplicity="*"/>
  <End Type="YoStat.Models.Examination" Role="VariablesPartner" Multiplicity="0..1"/>
</Association>
<Association Name="YoStat_Models_Variable_Examination_YoStat_Models_Examination_ExaminationPartner">
  <End Type="YoStat.Models.Examination" Role="Examination" Multiplicity="1"/>
  <End Type="YoStat.Models.Variable" Role="ExaminationPartner" Multiplicity="0..1"/>
</Association>

<EntityContainer Name="Container">
  <EntitySet Name="Examinations" EntityType="YoStat.Models.Examination"/>
  <EntitySet Name="Variables" EntityType="YoStat.Models.Variable"/>
  <AssociationSet Name="YoStat_Models_Examination_Variables_YoStat_Models_Variable_VariablesPartnerSet" Association="YoStat.Models.YoStat_Models_Examination_Variables_YoStat_Models_Variable_VariablesPartner">
    <End Role="VariablesPartner" EntitySet="Examinations"/>
    <End Role="Variables" EntitySet="Variables"/>
  </AssociationSet>
  <AssociationSet Name="YoStat_Models_Variable_Examination_YoStat_Models_Examination_ExaminationPartnerSet" Association="YoStat.Models.YoStat_Models_Variable_Examination_YoStat_Models_Examination_ExaminationPartner">
    <End Role="ExaminationPartner" EntitySet="Variables"/>
    <End Role="Examination" EntitySet="Examinations"/>
  </AssociationSet>
</EntityContainer>

As you can see, it generates two distinct associations instead of one. How to fix it? Thanks!


Solution

  • This looks like a bug in odata model builder, which always creates unidirectional navigation for each navigation property, while the better way is to look into the model to check if it's a bidirectional navigation first. I filed the bug at: http://aspnetwebstack.codeplex.com/workitem/623

    However, I didn't find anything broken in client side with current behavior. WCF DS client will still generate correct proxy classes. Do you have any specific user scenario which is blocked by it? The information will help the bug to be better triaged. Thanks.