0

I am working with two classes Company and Visitor that have a one-to-many relationship.

public class Company
{
    public int CompanyID { get; set; }
    public string CompanyName { get; set; }

    public virtual ICollection<Visitor> Visitors { get; set; }
}

public class Visitor
{
    public int VisitorID { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public int CompanyID { get; set; }
    public bool SendNewsletter { get; set; }

    public virtual Company Company { get; set; }
}

I have a page where a Visitor can fill out information about themselves. The idea is that if a Company is not in the db, it will get added to the list. If the CompanyName the Visitor enters matches a name in the db, the Company is associated with the Visitor, rounding out its required info, which is then added to its own db.

 var companyExists = db.Companies.Any(c => c.CompanyName == visitor.Company.CompanyName);
 if(companyExists)
 {
      var existingCompany = db.Companies.SingleOrDefault(c => c.CompanyName == visitor.Company.CompanyName);
      visitor.CompanyID = existingCompany.CompanyID;
      visitor.Company = existingCompany;
 }

 db.Visitors.Add(visitor);
 db.SaveChanges();

This code works but it seems redundant. I am associating the Visitor's CompanyID with the existing Company and then doing the same for the Company. Everything I read suggests that updating the Visitor's CompanyID should be sufficient but if I don't map the existingCompany to the Visitor's Company parameter, a second CompanyID is created. I feel like I'm missing some crucial point and am hoping someone here can point me in the right direction.

Kahbazi
  • 14,331
  • 3
  • 45
  • 76
Yusif_Nurizade
  • 133
  • 1
  • 12

1 Answers1

0

You don not need set visitor.Company. You can get Company information by CompanyID and you can use Where and FirstOrDefault to avoid redundant like this:

var companyExists = db.Companies.Where(c => c.CompanyName == visitor.Company.CompanyName).FirstOrDefault();
if (companyExists)
{
   visitor.CompanyID = companyExists.CompanyID;
   // visitor.Company = companyExists;
}

Notice that public virtual Company Company { get; set; } allows the Entity Framework to create a proxy around the virtual property so that the property can support lazy loading and more efficient change tracking. Please see this post for more information about virtual property in EF.

Ali Soltani
  • 9,589
  • 5
  • 30
  • 55
  • Thank you for your reply Ali. I tried what you suggested but the program is still creating a new ID for Visitor.Company.CompanyID which does not match with Visitor.CompanyID. Is there a simpler way to link the two? I thought it was lazy loading so I enabled it and got no change. – Yusif_Nurizade Sep 16 '17 at 05:14
  • @Yusif_Nurizade Are you adding `visitor` and `Company` in a block of code? – Ali Soltani Sep 16 '17 at 05:28
  • Ali Soltani could you please clarify what you mean? What block of code? I have the existing code at the top. If the Company exists, I do not add it, just associate the ID per your suggestion but that still creates a new Company with a different ID. – Yusif_Nurizade Sep 16 '17 at 05:31
  • @Yusif_Nurizade I've already encountered this problem. I think before `if (companyExists)` you filled `visitor.Company`. Add `visitor.Company = null` after `visitor.CompanyID = companyExists.CompanyID;` and check it again. – Ali Soltani Sep 16 '17 at 06:12
  • @Ani Soltani thank you for the suggestion but this is essentially the same as having visitor.Company = existingCompany; Is there a cleaner way to accomplish the task? I was hoping to set the ID and not create a new one in the partially written company. – Yusif_Nurizade Sep 17 '17 at 03:15