I have two classes, Company and CompanyAddress.
For every Company there can be multiple CompanyAddresses, such as Invoice address and correspondence address.
Via entity framework, I'm trying to include all CompanyAddresses that belong the Company. However, I keep getting the following debug error:
An exception of type 'System.InvalidOperationException' occurred in System.Data.Entity.dll but was not handled in user code
Additional information: A specified Include path is not valid. The EntityType 'StatelyTechAdmin.Models.Company' does not declare a navigation property with the name 'CompanyAddresses'.
Can anyone advise me on why I cannot include all addresses in my LINQ query? Please note I am very new to Entity Framework.
Company Class
public class Company
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public virtual long CompanyId { get; set; }
[Required]
[Display(Name = "Company Name")]
public virtual string Name { get; set; }
public virtual DateTime CreatedDate { get; set; }
public virtual IEnumerable<CompanyAddress> CompanyAddresses { get; set; }
}
CompanyAddress Class
public class CompanyAddress
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public virtual long CompanyAddressId { get; set; }
[Required]
public virtual long CompanyId { get; set; }
[ForeignKey("CompanyId")]
public virtual Company Company { get; set; }
[Required]
public virtual int CompanyAddressTypeId { get; set; }
[ForeignKey("CompanyAddressTypeId")]
public virtual CompanyAddressType CompanyAddressType { get; set; }
[Display(Name = "Address 1")]
public virtual string Address1 { get; set; }
[Display(Name = "Address 2")]
public virtual string Address2 {get; set; }
[Display(Name = "Town")]
public virtual string Town { get; set; }
[Display(Name = "City")]
public virtual string City { get; set; }
[Required]
public virtual long CountyId { get; set; }
[ForeignKey("CountyId")]
[Display(Name = "County")]
public virtual County County { get; set; }
[Required]
[Display(Name = "Postal Code")]
public virtual string PostalCode { get; set; }
public virtual DateTime CreatedDate { get; set; }
}
Calling Method from MVC Action
public ActionResult Index()
{
var comp = db.Companies.Include(a => a.CompanyAddresses).ToList();
return View(comp);
}
All advice welcome! Thank you for your time.
You can't use IEnumerable for your navigation property. You need to use ICollection or a type derived from it.
How do I load related entities of type IEnumerable<T>
Related
I have the following architecture:
public abstract class ApplicationDriverFormAbstractVM : IValidatableObject
{
[Display(Name = "Job applied For")]
public virtual string JobAppliedFor { get; set; }
[Display(Name = "Has any license, permit, or privilege ever been suspended, revoked, or denied?")]
public virtual bool? HasDeniedLicenses { get; set; }
[Display(Name = "Have you ever been convicted for driving under the influence of drugs or alcohol?")]
public virtual bool? HasAlcohol { get; set; }
[Display(Name = "Have you ever tested positive or refused to test on any pre-employment drug and / or alcohol test administered by an employer to which you applied for but did not obtain safety sensitive transportation work covered by DOT agency drug and alcohol testing rules during the past 2 years?")]
public virtual bool? HasDOTAlcohol { get; set; }
[Display(Name = "Have you ever been convicted of a felony or misdemeanor?")]
public virtual bool? HasFelony { get; set; }
public class ApplicationDriverEditVM : ApplicationDriverFormAbstractVM
{
[Required]
public override string JobAppliedFor { get; set; }
[Required]
public override bool? HasDeniedLicenses { get; set; }
[Required]
public override bool? HasAlcohol { get; set; }
[Required]
public override bool? HasDOTAlcohol { get; set; }
[Required]
public override bool? HasFelony { get; set; }
}
but this [Required] attribute does not work on client side. If I remove inheritance and have only one class with [Required] attributes it works fine. Why so?
I don't really understand what's happening here. From my research I gather that entity is trying to guess the name of a foreign key and it's not there, so it's throwing an "Invalid Column Name" error. The problem is that the model/table in question does not have any foreign keys. So I'm really confused.
Here's the code that throws the error:
foreach (TechnologyProjectPlanModel result in results)
{
//get approvers for plan
int id = result.Id;
try
{
List<ApprovalModel> approvers = db.ApprovalModels.Where(m => m.FormId == result.Id).Select(m => m).ToList(); //ERROR HERE
if (approvers != null)
{
result.Approvers = approvers.ToList();
}
}
catch (Exception e)
{
}
}
Here's the ApprovalModel:
public class ApprovalModel
{
[Key]
public int Id { get; set; }
public int ApprovalProcessId { get; set; }
public int FormId { get; set; }
public int UserId { get; set; }
public bool? Approved { get; set; }
}
And here's the TechnologyProjectPlanModel referenced in the foreach loop:
public class TechnologyProjectPlanModel
{
[Key]
public int Id { get; set; }
public int FormId { get; set; }
public int UserId { get; set; }
public string FormType { get; set; }
public int Status { get; set; }
public int Hidden { get; set; }
public DateTime DateSubmitted { get; set; }
public DateTime DateFinalized { get; set; }
public List<QuoteUploadsModel> Quotes { get; set; }
public List<ApprovalModel> Approvers { get; set; }
[Required]
[Display(Name = "Please Select Your School")]
public string School { get; set; }
[Required]
[Display(Name = "Requestor")]
public string Requestor { get; set; }
[Display(Name = "Title")]
public string Title { get; set; }
[Required]
[DataType(DataType.PhoneNumber)]
[Display(Name = "Phone Number")]
[Phone]
public string PhoneNumber { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
[Display(Name = "Email Address")]
[EmailAddress]
public string Email { get; set; }
[Required]
[Display(Name = "Project Title")]
public string ProjectTitle { get; set; }
[Display(Name = "Requested Completion Date")]
public DateTime RequestedCompletionDate { get; set; }
[Required]
[Display(Name = "Project Description")]
public string ProjectDescription { get; set; }
[Display(Name = "Teacher/Room Number")]
public string TeacherGroup { get; set; }
[Display(Name = "1")]
public bool Grade1 { get; set; }
[Display(Name = "2")]
public bool Grade2 { get; set; }
[Display(Name = "3")]
public bool Grade3 { get; set; }
[Display(Name = "4")]
public bool Grade4 { get; set; }
[Display(Name = "5")]
public bool Grade5 { get; set; }
[Display(Name = "6")]
public bool Grade6 { get; set; }
[Display(Name = "7")]
public bool Grade7 { get; set; }
[Display(Name = "8")]
public bool Grade8 { get; set; }
[Display(Name = "9")]
public bool Grade9 { get; set; }
[Display(Name = "10")]
public bool Grade10 { get; set; }
[Display(Name = "11")]
public bool Grade11 { get; set; }
[Display(Name = "12")]
public bool Grade12 { get; set; }
[Display(Name = "Kindergarten")]
public bool Kindergarten { get; set; }
[Display(Name = "Describe how this plan will be continued if events cause programs or equipment to no longer be available. For example, if equipment purchased needs repair what funding source will be used for repair or replacement? For programs that have annual subscription fees, what funds will be used to continue the program from year to year?")]
public string Sustainability { get; set; }
public bool MultipleFundingSource { get; set; }
[Required(ErrorMessage="*")]
[Display(Name = "Funding Source")]
public string FundingSource1 { get; set; }
[Required(ErrorMessage = "*")]
public string FundingSource2 { get; set; }
[Required(ErrorMessage = "*")]
public string FundingSource3 { get; set; }
[Required(ErrorMessage = "*")]
public string FundingSource4 { get; set; }
[Required(ErrorMessage = "*")]
public string FundingSource5 { get; set; }
[Required]
[Display(Name = "Total Estimated Project Costs:")]
public float TotalEstimatedProjectCosts { get; set; }
//----------------------Additional Information
[Display(Name = "Additional Comments:")]
public string AdditionalComments { get; set; }
[Display(Name = "Additional Supporting Documents:")]
public string AdditionalSupportingDocuments { get; set; }
}
The exact error is:
An error occurred while executing the command definition. See the inner exception for details.
Inner Exception:
Invalid column name 'TechnologyProjectPlanModel_Id'.
That column name isn't referenced anywhere in my code, so it must be inferring it from something.
Any ideas? Thanks!
Entity Framework relies on conventions to determine what it thinks your DB looks like. In this case, it thinks the ApprovalModel table should have a foreign key to the TechnologyProjectPlanModel table. Trimming down your entities to the relevant fields, it becomes apparent why it thinks this:
public class ApprovalModel
{
}
public class TechnologyProjectPlanModel
{
public List<ApprovalModel> Approvers { get; set; }
}
In database terms, the relationship that would most likely exist in order for there to be multiple ApprovalModel's per TechnologyProjectPlanModel would be for ApprovalModel's to have a foreign key to TechnologyProjectPlanModel's.
How does TechnologyProjectPlanModel.Approvers get set? If it doesn't have anything to do with Entity Framework and you don't want it to try populating this property via it's conventions, you can explicitly tell it not to make that assumption by telling it the property is not mapped like so:
[NotMapped]
public List<ApprovalModel> Approvers { get; set; }
If you do have this relationship, you need to give EF some more context so it doesn't make best guess assumptions. For example, if the foreign key does exist, place it in ApprovalModel along with the relevant navigation property that can further tell EF what your DB looks like:
public class ApprovalModel
{
public int TechnologyProjectPlanModelId { get; set; }
// ForeignKey attribute usually not necessary unless you need to tell EF
// about a property that doesn't follow the usual "{OtherEntityName}Id"
// naming convention.
[ForeignKey("TechnologyProjectPlanModelId")]
public TechnologyProjectPlanModel TechnologyProjectPlanModel { get; set; }
}
public class TechnologyProjectPlanModel
{
public List<ApprovalModel> Approvers { get; set; }
}
You know if you do the mapping correctly, that block of code is unnecessary because EF will retrieve results.Approvers for you.
You can use the Attribute based mapping directly on your model or you can use the Code First Configuration to map your foreign key properly.
Once you've properly mapped the foreign key, the block of code you pasted is unnecessary, EF does the load for you.
I have a Project table with some fields that point to a Participant table but all with a different meaning of course:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace iMaSys.Models
{
public class Project
{
[Key]
public int ProjectID { get; set; }
[Required]
[StringLength(128)]
[Display(Name = "Omschrijving")]
public string Description { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
[Display(Name = "Startdatum")]
public DateTime StartDate { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
[Display(Name = "Einddatum")]
public DateTime? EndDate { get; set; }
public Boolean Active { get; set; }
[Display(Name = "Mediation Casenummer")]
public string Mediation_casenr { get; set; }
public Participant CaseManager { get; set; }
public Participant Supervisor { get; set; }
public Participant Party_1 { get; set; }
public Participant Party_2 { get; set; }
public Participant Client { get; set; }
public Participant InterventionManager { get; set; }
public Participant Mediator { get; set; }
public virtual ProjectCategorySub ProjectCategorySubject { get; set; }
}
}
The fields Casemanager, Supervisor, Party_1 etc all point to Participant. In Particpant I added InverseProperties to tell the framework the connection between Projects and Participants:
[InverseProperty("Mediator")]
public List<Project> ProjectMediators { get; set; }
[InverseProperty("Supervisor")]
public List<Project> ProjectSupervisors { get; set; }
etc. etc.
After add-migration and update-database the fields in Project are named like:
CaseManager_ParticipantID etc. I just simply need CaseManagerID to point to Participant_ParticipantID. I tried several things but I seem not to understand howto get it to work.
I'm stuck on this one, can anyone point me in the right direction?
Best regards, Janno Hordijk
I solved it myself but want to share what I found out.
At Participant:
[InverseProperty("Mediator")]
public virtual ICollection<Project> MediatorProjects { get; set; }
[InverseProperty("Supervisor")]
public virtual ICollection<Project> SupervisorProjects { get; set; }
At Project:
[ForeignKey("Mediator")]
public int? Mediator_ID { get; set; }
public virtual Participant Mediator { get; set; }
[ForeignKey("Supervisor")]
public int? Supervisor_ID { get; set; }
public virtual Participant Supervisor { get; set; }
Now the database is ok and my fieldnames are Supervisor_ID instead of Supervisor_Participant_ID
Best regards, Janno
I am new to MVC. I am trying to create CRUD for Engineer entity for which I have written following modal class.
public abstract class Person
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required(ErrorMessage="first name required")]
[MaxLength(50)]
[DisplayName("First Name")]
public string FirstName { get; set; }
[MaxLength(50)]
[DisplayName("Middle Name")]
public string MiddletName { get; set; }
[Required(ErrorMessage = "last name required")]
[MaxLength(50)]
[DisplayName("Last Name")]
public string LasttName { get; set; }
}
public class Engineer : Person
{
[Required]
[MaxLength(50)]
[DisplayName("Qualification")]
public string Qualification { get; set; }
public Address Address { get; set; }
}
Now When I add controller for the Engineer with read/write actions and views with entity framework, my Views(Create/Index/Delete/Details/Edit) for Engineer does include Address class fields. But when I run the project I could see address fields in Engineer Table in backend. where am I getting wrong.
Hello I'm new to mvc 3 and I need some pointers/help populating a dropdownlist. I have 3 classes which are my domain classes. Basically what I want to do is make a dropdownlist that will be populated with a specific members rented movies. What is the easiest way to do this? Is it to use the ViewBag or to make a ViewModel?
public class Member
{
public virtual int MemberId { get; set; }
public virtual long PersonalNr { get; set; }
public virtual string Name { get; set; }
public virtual string LastName { get; set; }
public virtual List<Rental> Rentals { get; set; }
}
public class Movie
{
public virtual int MovieId { get; set; }
public virtual string Name { get; set; }
public virtual bool IsInStock { get; set; }
}
public class Rental
{
public virtual int RentalId { get; set; }
public virtual int MovieId { get; set; }
public virtual Movie Movie { get; set; }
public virtual int MemberId { get; set; }
public virtual Member Member { get; set; }
public DateTime startDate { get; set; }
public DateTime dueDate { get; set; }
}
The easiest way is
#Html.DropDownListFor(
x => x.SelectedRentalId,
Model.Rentals
)
to know a little better on how to use it, including the select part, se Darin's answer
https://stackoverflow.com/a/6807331/28004