I have three entities: Districts, Sites, and Repayments (Actually there are about a dozen, but these are the important ones). THe Relavent Code is:
public class Site
{
[Key, Column(Order = 0)]
public int DistrictId { get; set; }
[Key, Column(Order = 1)]
public int SiteId { get; set; }
public string Name { get; set; }
public virtual District District { get; set; }
}
public class District
{
public int DistrictId { get; set; }
public string Name { get; set; }
public virtual ICollection<Repayment> Repayments { get; set; }
}
public class Repayment
{
[Key, Column(Order = 0)]
public int DistrictId { get; set; }
[Key, Column(Order = 1)]
public int RepaymentId { get; set; }
public string Name { get; set; }
[InverseProperty("Repayments")]
[ForeignKey("DistrictId")]
public virtual District District { get; set; }
}
Then, in the FluentAPI I have:
modelBuilder.Entity<Repayment>().HasRequired(r => r.District)
.WithMany(d => d.Repayments)
.HasForeignKey(r => new { r.DistrictId});
The model performs correctly on the C# side, making repayments a collection in a District when I use the appropriate Include clause. Breeze, however, cannot find the repayments collection under the district (the repayments are in cache under a couple of other entities). I have tried every combination of Fluent API and Data Annotation possible (using only data annotation, using partial data annotation with and without the fluent api, etc) and there is no difference.
An interesting aside, the client side code works perfectly (and populates the repayments under districts) when I run it against a 1.5.1 version of Context Provider and 2.1.5.1 version of BreezeWebApi (the version that is not working is 1.5.2 and 2.1.5.2). However, I'm porting from a less complex model to a more complex model, so the backend is not exactly the same (those these classes are byte for byte the same).
I'd be grateful for any ideas.
EDIT: I have just installed the more recent versions (2.1.5.2 and 1.5.2) on the working site, and it caused no problems. So the version change doesn't seem to be the culprit. Are there any other things I should be checking?
TIA
EDIT: Even more information There are, within a district, 10 total one-to-many navigation propertys, of which Repayments is only one. 8 of them are being populated correctly (and are defined in exactly the same way) and two (including the Repayments property) are not. On the server side, all 10 properties are recognized and populated, while on the client side Breeze is only "wiring up" 8 of the properties to District (all the related entities are in cache and wired to at least one other entity, just not the District entity). Very strange. Help?
EDIT: Curiouser and curiouser: The breeze metadata seems to have the appropriate navigation property definitiions. Below is the NavProp definitions for Repayments (not working) and SeasonClients (working) in the District Entity:
{
"name": "Repayments",
"relationship": "Self.Repayment_District",
"fromRole": "Repayment_District_Target",
"toRole": "Repayment_District_Source"
},
{
"name": "SeasonClients",
"relationship": "Self.SeasonClient_District",
"fromRole": "SeasonClient_District_Target",
"toRole": "SeasonClient_District_Source"
},
And here is how the Nav Property for District is defined in both entities:
REPAYMENT Nav Properties:
{
"name": "District",
"relationship": "Self.Repayment_District",
"fromRole": "Repayment_District_Source",
"toRole": "Repayment_District_Target"
},
SEASON CLIENT Nav Properties:
{
"name": "District",
"relationship": "Self.SeasonClient_District",
"fromRole": "SeasonClient_District_Source",
"toRole": "SeasonClient_District_Target"
},
And here is the SeasonClient_District relation definition:
{
"name": "SeasonClient_District",
"end": [{
"role": "SeasonClient_District_Source",
"type": "Edm.Self.SeasonClient",
"multiplicity": "*"
},
{
"role": "SeasonClient_District_Target",
"type": "Edm.Self.District",
"multiplicity": "1",
"onDelete": {
"action": "Cascade"
}
}],
"referentialConstraint": {
"principal": {
"role": "SeasonClient_District_Target",
"propertyRef": {
"name": "DistrictId"
}
},
"dependent": {
"role": "SeasonClient_District_Source",
"propertyRef": {
"name": "DistrictId"
}
}
}
},
Which is byte-for-byte the same (if you replace 'SeasonClient' with 'Repayment') as the Repayment_District relationship definition.
Any thoughts?
DbContext. The gambit? Create a subclass of thatDbContextthat hides the stuff you don't want to expose. You can use that for Metadata generation or even for your own api if you wish. It has no logic in it and won't encumber your team in any way. - Ward