44

I have a class AgentBalance with an association to Agent, thus:

public class AgentBalance
{
    ...

    public int AgentId { get; set; }

    public virtual Agent Agent { get; set; }

}

AgentId is detected as the FK for the Agent relationship by convention, but I want to make it explicit in the Mapping class, to be safer against future changes. If Agent had a collection of Balances then I know how to do this e.g.:

HasRequired(t => t.Agent).WithMany(a => a.Balances).HasForeignKey(t => t.AgentId);

However, Agent does not have a collection of Balances - I don't want that association to be reverse navigable. But without the .WithMany in the mapping I don't get the option to specify .HasForeignKey. Is there another way? (N.B. I know I could also do this using attributes, but I want to use the fluent API mapping).

gavriln
  • 19
  • 3
Richard Pawson
  • 1,494
  • 1
  • 10
  • 15

2 Answers2

69

I believe you should be able to do this:

HasRequired(t => t.Agent).WithMany().HasForeignKey(t => t.AgentId)
SOfanatic
  • 5,523
  • 5
  • 36
  • 57
  • 10
    Thanks - I had missed that WithMany() was overloaded! Still, seems an odd syntax. I don't see why they couldn't have let you write something like: HasRequired(t => t.Agent).HasForeignKey(t => t.AgentId) – Richard Pawson Oct 14 '13 at 12:17
  • 1
    There wouldn't be a way for EF to know what type of relationship it is. – SOfanatic Oct 14 '13 at 12:46
  • 2
    This does not work for me. EF creates a new Agent_Id column, besides my AgentId that I have explicitly configured as a foreign key column. Do you know why this is happening? – Yulian Feb 11 '15 at 14:29
  • Same, I have found that whenever I try to explicitly set the foreign key, the explicit migration script is completely messed up, crazy... – tobiak777 Feb 25 '15 at 16:02
  • 1
    @Yukian @red2nb it's probably because you need to specify the appropriate mapping in `WithMany()` when you have the collection on the other entity. For example, `.WithMany(agent => agent.Balances)` – David Sherret May 04 '15 at 02:42
  • @DavidSherret Yea you're right. Afterwards I found it out too, I lacked the configuration! More generally, I noticed that most of the time when a Migration scripts is messed up, it's only because the configuration is wrong. – tobiak777 May 04 '15 at 09:37
1

I prefer to use Data Annotations for these tasks, not Fluent API. It is much shorter end easy to understand. EF must detect properties ended with "Id" automatically, but to be on a safe side you can specify them explicitly:

using System.ComponentModel.DataAnnotations.Schema;
...
public int AgentId { get; set; }

[ForeignKey("AgentId")]
public virtual Agent Agent { get; set; }

You will need to specify them explicitly if your FK prop are not ended with "Id", for example:

public int AgentCode { get; set; }

[ForeignKey("AgentCode")] // now this is needed if you'd like to have FK created
public virtual Agent Agent { get; set; }

You can find more details here: https://msdn.microsoft.com/en-us/data/jj591583.aspx

fifonik
  • 1,556
  • 1
  • 10
  • 18
  • 10
    Data Annotations is, I agree, easier to read. But it is not, IMO, a good way to manage things on a very large scale complex project, which is my context. – Richard Pawson Mar 11 '15 at 09:05
  • @RichardPawson why not? – gsharp May 27 '16 at 11:19
  • 3
    @gsharp it's because DataAnnotations is not as powerful as Fluent API, so in a large project you are always going to need to use Fluent API because DataAnnotations won't suffice and when this happens you end up with configuration in two places and it's better to just have all the configuration for a model in one place. – SOfanatic Sep 29 '16 at 13:29
  • @SOfanatic in the meantime I agree with you. Iv'e started as a newbie with data annotations and switched pretty soon to Fluent API. However i prefer to inherit from EntityTypeConfiguration and have a config per entity. – gsharp Sep 29 '16 at 15:12
  • @gsharp yes that's the right approach, you probably even want to create your own "Base" class for EntityTypeConfiguration that way you can auto register the configurations when the db is initialized – SOfanatic Sep 29 '16 at 20:10
  • I agree the syntax is overly complex. Should be as simple as Entity(ab => ab.AgentId).HasForeignKey(a => a.AgentId); – Geekn Sep 15 '18 at 23:32