I have these two classes:
public class Foo
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
// ...
// Foo has N bars, 1 of which is primary
[ForeignKey("Bar")]
public int? PrimaryBarId { get; set; }
public virtual Bar PrimaryBar { get; set; }
}
public class Bar {
[Key]
public int Id { get; set; }
public string Name { get; set; }
// ...
// Foo -> Bar == 1:N
[ForeignKey("Foo")]
public int FooId { get; set; }
public virtual Foo Foo { get; set; }
}
EF now expects me to create a property BarId
and Bar
on Foo
but I don't want that. I want the property to be named PrimaryBar. I have a 1:N relationship on Foo
->Bar
which is reflected elsewhere and not of interest for this question.
EF keeps telling me:
The ForeignKeyAttribute on property 'PrimaryBarId' on type 'X.y.Foo' is not valid. The navigation property 'Bar' was not found on the dependent type 'X.y.Foo'. The Name value should be a valid navigation property name.
How do I convince EF to use the PrimaryBar
(and PrimaryBarId
) properties (preferrably with an attribute, although using the DbModelBuilder
in the OnModelCreating
override is an option too?
EDIT
Figured it out. I was missing a:
public virtual ICollection<Bar> Bar { get; set; }
on my Foo
class. See here for the explanation.
I'm terribly sorry, but none of the answers were correct. That is: they are correct (probably) but I posted my example code for the question wrong. First I forgot to rename some types/properties, then I found a mistake in the the errormessage I posted. And finally it turns out I forgot to post the following code I had on my Bar
class:
class Bar {
//Didn't post this code:
[ForeignKey("Foo")]
public int FooId { get; set; }
public virtual Foo Foo { get; set; }
}
This code was for the 1:N Foo
has to Bar
. But since the PrimaryBar
property implies a 1:0..1 relation EF got confused I guess. What I was missing was the following on my Foo
class to contain the 1:0..N with Bar
:
class Foo {
public virtual ICollection<Bar> Bars { get; set; }
}
I added this collection et voila; everything works fine now.
Oh, I did have to change the ForeignKey to PrimaryBar
instead of Bar
indeed as most answers suggested.
I'm terribly sorry and mea culpa: all f*ckups were mine and my own only. I usually don't prefer to post "Foo/Bar/Baz" code instead of actual code but in this case it was a bit difficult and the classes would raise (unrelated) questions on their own which I didn't want to discuss :P
I have upvoted all answers as a "thank you"; however since none of them was the actual solution, again because of my being a dumbass and posting incorrect code/information, I have posted my own answer.
As per the documentation, the Name
provided to the ForeignKeyAttribute
should be the property name not the type or table name. So change your code to this:
public int? PrimaryBarId { get; set; }
[ForeignKey("PrimaryBarId")]
public virtual Bar PrimaryBar { get; set; }
Or:
[ForeignKey("PrimaryBar")]
public int? PrimaryBarId { get; set; }
public virtual Bar PrimaryBar { get; set; }