2

I want a list of contact with a company. But Company is referenced by ContactExtension and ContactExtension is referenced by Contact. I'm not sure it's possible but I try this:

[Table("Company", Schema = "dbo")] 
public class Company
{
    [Column("ID")]
    [Key]
    public int ID { get; set; }
    [Column("Name")]
    public String Name { get; set; }
    [ForeignKey(?)]
    public virtual ICollection<Contact> MyContacts { get; set; }
}

[Table("Contact", Schema = "dbo")]
public class Contact
{
    [Column("ID")]
    [Key]
    public int ID { get; set; }
    [Column("Name")]
    public String Name { get; set; }
    [Column("ContactExtensionID")]
    public int ContactExtensionID { get; set; }
    [ForeignKey("ContactExtensionID")]
    public virtual ContactExtension ContactExtension { get; set; }
}

[Table("ContactExtension", Schema = "dbo")]
public class ContactExtension
{
    [Column("ID")]
    [Key]
    public int ID { get; set; }
    [Column("Name")]
    public String Name { get; set; }
    [Column("CompanyID")]
    public int CompanyID { get; set; }
}

If I write ForeignKey["CompanyID"], there is a problem because there is no CompanyID column in Contact.

How can I specify the foreignKey CompanyID is in ContactExtension?

I want to find a solution without Fluent Api.

Jonas
  • 88
  • 7
  • Are you using `Fluent API`? – Mark C. Mar 30 '15 at 15:01
  • No I want to find a solution without Fluent Api – Jonas Mar 30 '15 at 15:02
  • Have you seen [this](http://stackoverflow.com/questions/11148662/mapping-a-foreign-key-with-a-custom-column-name-in-entity-framework-4-3-code-fir) ? – Mark C. Mar 30 '15 at 15:05
  • Yes but the Foreign Key is not in Contact, it's in ContactExtension – Jonas Mar 30 '15 at 15:09
  • Where is the `virtual` property for `Contact` from `ContactExtension`? – Mark C. Mar 30 '15 at 15:16
  • There is a `virtual` property for `ContactExtension` from `Contact`, you think I need to create a `virtual` property `Contact` ? – Jonas Mar 30 '15 at 15:20
  • So, a company has 1:M contacts, which have 1:1 Contact Extensions. I'm not sure why Company ID or Contact Extensions are their own entity. but anything that has a relationship with another entity I would expect to see a virtual property for. In my opinion, CompanyID should be on the Contact entity. – Mark C. Mar 30 '15 at 15:25
  • I can't change the database design. – Jonas Mar 30 '15 at 15:29
  • In `Company`, you're telling EF that there's a 1:M relation between `Company` and `Contact`. `Contact` has no identifiable relationship, *from your code*, to `Company`, but has a 1:1 relationship with `ContactExtension`. Therefore, your `Company` entity is **actually related to** your `ContactExtension` entity. I would expect to see this change your `virtual property` for `Company` – Mark C. Mar 30 '15 at 15:32
  • I want to do this : ContactExtension.CompanyID – Jonas Mar 30 '15 at 16:29

1 Answers1

1

Forget about a direct relation 1 to N between Companies and ContactExtensions tables. That connection exists through the Contacts table.

Then, if you want to reference a ContactExtensions from a Company instance you would do:

var tenthContact = company.Contacts.ElementAt(10);
var contactExtension = tenthContact.ContactExtension;

If you want to do:

var companyContactExtensions = company.ContactExtensions;

You can just create a ContactExtensions property that computes that for you and does not get mapped to the database. Inside your Company class:

public ICollection<CompanyExtension> CompanyExtensions
{
      get
      {
          return this.CompanyContacts.SelectMany(c => c.ContactExtension).ToList();
      }
}

UPDATE

Just read your last comment: I want to do this : ContactExtension.CompanyID.

The solution is the same. Since you have a Contacts entity/table in the middle, that direct connection doesn't exist.

If you really want that property you can use the 1 to 1 relationship between Contact and ContactExtension and then reference the company:

companyExtension.Contact.Company.CompanyID

For this you would create a property Contact linking to Contact class in the ContactExtension class and another property Company linking to Company class in the Contact class.

In order to do it directly, you create another property not mapped to the database that computes that for you:

public int CompanyID
{
  get
  {
    return this.Contact.Company.CompanyID;
  }
}

PS: I think you think you created a connection from Company to Contact and from Contact to ContactExtensions but it wasn't really "from... to". Those connections are "between" and, therefore, you can link in the opposite direction.

Entity Framework understands what you mean and the database structure will be kept the same.


Alternatively, if you have a connection of 1 to 1 between Contacts and ContactExtensions, you could have everything in the same table.

Fabio Milheiro
  • 8,100
  • 17
  • 57
  • 96