Entity Framework Navigation Property on many-to-one relationship - c#

Edited
I am trying to set up a many-to-one relationship on two tables I have got but I am unable to manage to make it work. I tried different options but I end up retrieving records of only one table.
Below is my table structure:
Customer
[Table("Customer")]
public class CustomerList
{
[Key]
public int CustomerID { get; set; }
public int Number { get; set; }
public string Surname { get; set; }
public string Forename { get; set; }
public DateTime? DateOfBirth { get; set; }
public int? MembershipTypeID { get; set; }
public MembershipTypeList MembershipType { get; set; }
public string Name;
public string EmailAddress { get; set; }
}
MembershipType
[Table("MembershipType")]
public class MembershipTypeList
{
[Key]
public int? MembershipTypeID { get; set; }
public string Name { get; set; }
//public virtual CustomerList Customer { get; set; }
}
Result
CustomerID 56
Number 52
Surname Antonelli
Forename Renny
DateOfBirth 1945-02-19
MembershipTypeID 1
EmailAddress Mr#test.com
Name NULL
Expected
CustomerID 56
Number 52
Surname Antonelli
Forename Renny
DateOfBirth 1945-02-19
MembershipTypeID 1
EmailAddress Mr#test.com
Name Blue ---> from membershiptype table

Related

Entity Framework Code First Renaming Columns/Keys

I have an Employee table that links employees to their contact info. I have it set up like so:
[ForeignKey("AddressId")]
public virtual Address Address { get; set; }
[ForeignKey("HomePhoneId")]
public virtual PhoneNumber HomePhone { get; set; }
[ForeignKey("WorkPhoneId")]
public virtual PhoneNumber WorkPhone { get; set; }
[ForeignKey("CellPhoneId")]
public virtual PhoneNumber CellPhone { get; set; }
When I try to load employees from the database, however, it automatically renames the columns, completely overriding the attributes:
Invalid column name 'PhoneNumber_Id'.
Invalid column name 'PhoneNumber_Id1'.
Invalid column name 'PhoneNumber_Id2'.
Invalid column name 'Address_Id'.
Why is it doing this?
As stated by #mcbowes, it is hard to tell without seeing the rest of your Employee class, but most likely you are missing the following in your class:
public int AddressId { get; set; }
public int HomePhoneId { get; set; }
public int WorkPhoneId { get; set; }
public int CellPhoneId { get; set; }
The IDs were all properly specified for each navigation property. It seems the problem had to do with the navigation properties on each PhoneNumber and Address object that linked back to the Employee. I don't need them for now, so removing those navigation properties corrected the issue.
As an expansion on #peinearydevelopment set up your PhoneNumber:
public class PhoneNumber
{
public PhoneNumber(string name, int areaCode, string number)
{
Name = name;
AreaCode = areaCode;
Number = number;
}
public int ID { get; set; }
public string Name { get; set; }
public int AreaCode { get; set; }
public string Number { get; set; }
}
}
Set up your Employee:
public class Person
{
public Person(string first, string last, PhoneNumber home, PhoneNumber cell)
{
First = first;
Last = last;
HomeNumber = home;
CellNumber = cell;
}
public int ID { get; set; }
public string First { get; set; }
public string Last { get; set; }
public int HomePhone_ID { get; set; }
public int CellNumber_ID { get; set; }
public virtual PhoneNumber HomeNumber { get; set; }
public virtual PhoneNumber CellNumber { get; set; }
}
}
And your Context
public class PersonContext : DbContext
{
public DbSet<Person> People { get; set; }
public DbSet<PhoneNumber> PhoneNumbers { get; set; }
}
As you can see, relationships are maintained, but you do need to explicitly tell your application which fields hold the identifiers, not just which tables have the relationships.

entity hasoptional foreign keyone to one

I have this class:
public class CommunityUser : BaseEntity
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public int CustomerId { get; set; }
public DateTime CreatedOnUtc { get; set; }
public int ForumPostsNumber { get; set; }
public virtual Customer Customer { get; set; }
}
How to use entity framework mapping to say that a CommunityUser has an optional CustomerId that is a foreign key on the Customer Table?
You must make your foreign key nullable by making it int?
public class CommunityUser : BaseEntity
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public int? CustomerId { get; set; }
public DateTime CreatedOnUtc { get; set; }
public int ForumPostsNumber { get; set; }
public virtual Customer Customer { get; set; }
}

How to configure relationship using Entity framework fluent api for below use case

I am working with Code First approach and i have designed below classes.
public interface IItem
{
public Guid ItemId { get; set; }
DateTime? CreateDate { get; set; }
DateTime? ModifyDate { get; set; }
User CreatedBy { get; set; }
User ModifiedBy { get; set; }
}
public class User : IItem
{
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Name { get; set; }
public Guid ItemId { get; set; }
public DateTime? CreateDate { get; set; }
public DateTime? ModifyDate { get; set; }
public User CreatedBy { get; set; }
public User ModifiedBy { get; set; }
}
public class Entity1 : IItem
{
public string Entity1Prop1 { get; set; }
public Guid ItemId { get; set; }
public DateTime? CreateDate { get; set; }
public DateTime? ModifyDate { get; set; }
public User CreatedBy { get; set; }
public User ModifiedBy { get; set; }
}
Now i need to define relation between the entities using fluent API.
I have below requirement
1. User table has primary key ItemId
2. User table colulmns CreatedBy and ModifiedBy reference to same user table ItemId column as ForeignKey
3. Entity1 table has primary key ItemId
4. Entity table columns CreatedBy and ModifiedBy references to user table itemId as foreign key

Entity Framework mapping one class across two tables with a condition

I'm trying to map one class to two database tables. I have a Person Class that maps to a Person table and an Address table. My problem is I only want to select the Primary Address Line (IsPrimary = 1) of the Address table and I can't find or figure out how to do this.
I'm using Entity Framework v6 CodeFirst and I trying to create the EntityTypeConfiguration<T> class
The domain class is...
public class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
// Primary Address
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressLine3 { get; set; }
public string AddressPostCode { get; set; }
}
and the database tables look like this...
Table: Person
Int PersonId (PK)
Varchar(20) FirstName Not Null
Varchar(20) LastName Not Null
Table: Address
Int AddressId (PK)
Int PersonId (FK)
Varchar(25) AddressLine1 Null
Varchar(25) AddressLine2 Null
Varchar(25) AddressLine3 Null
Varchar(10) PostCode Not Null
Bit IsPrimary Not Null
Basically one Person can have multiple addresses but only One Primary Address.
If you are using Entity Framework, probably you have these following classes with a one to many relation:
public class PersonEntity
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual ICollection<AddressEntity> Addresses { get; set; }
}
public class AddressEntity
{
public int AddressId { get; set; }
public int PersonId { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressLine3 { get; set; }
public string AddressPostCode { get; set; }
public bool IsPrimary{ get; set; }
}
And as you mentioned in you'r question, this is the person viewmodel:
public class PersonViewModel
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
// Primary Address
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string AddressLine3 { get; set; }
public string AddressPostCode { get; set; }
}
Finally you can use the following linq code:
var result = ctx.PersonEntity
.Where(c => c.Addresses.FirstOrDefault(X = > X.IsPrimary == true)).ToList();
var personViewModels = result
.Select(c => new PersonViewModel{
PersonId = c.PersonId ,
FirstName = c.FirstName ,
LastName = c.LastName,
AddressLine1 = c.Addresses != null ? c.Addresses.FirstOrDefault().AddressLine1 : String.Empty ,
AddressLine2 = c.Addresses != null ? c.Addresses.FirstOrDefault().AddressLine2 : String.Empty ,
AddressLine3 = c.Addresses != null ? c.Addresses.FirstOrDefault().AddressLine3 : String.Empty });

EntityFramework changing my query - EntityCommandExecutionException

I'm getting a 'EntityCommandExecutionException' and
An error occurred while executing the command definition. See the inner exception for details.
with an inner message of
Invalid column name 'Department_ID'
This seems to be the query executed from this line of code:
List<Employee> _employees = employeeContext.Employees.ToList();
SELECT [Extent1].[EmployeeID] AS [EmployeeID],
[Extent1].[Name] AS [Name],
[Extent1].[Gender] AS [Gender],
[Extent1].[City] AS [City],
[Extent1].[DepartmentID] AS [DepartmentID],
[Extent1].[DateOfBirth] AS [DateOfBirth],
[Extent1].[Department_ID] AS [Department_ID]
FROM [dbo].[tblEmployee] AS [Extent1]
This is wrong considering there is no Department_ID, I have no idea where it is getting this from. This is the Employee class model:
[Table("tblEmployee")]
public class Employee
{
public int EmployeeID { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public string City { get; set; }
public int DepartmentID { get; set; }
public DateTime DateOfBirth { get; set; }
}
[Table("tblDepartment")]
public class Department
{
public Int16 ID { get; set; }
public string Name { get; set; }
public List<Employee> Employees { get; set; }
}
Not sure what to do. Any ideas?
The Department_ID is coming by virtue of the relationship in your Department class. You have a List Employees there which automatically assumes a column called Department_ID in your Employee table.
What you need to do is add a virtual property called Department in your Employee table instead of adding the DepartmentID
[Table("tblEmployee")]
public class Employee
{
public int EmployeeID { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public string City { get; set; }
public virtual Department Department { get; set; }
public DateTime DateOfBirth { get; set; }
}
If you need to maintain the column name as DepartmentID or you need access to the property DepartmentID in code, then you need to use the ForeignKey attribute as shown below:
public class Employee
{
public int EmployeeID { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public string City { get; set; }
public int DepartmentID { get; set; }
[ForeignKey("DepartmentID")]
public virtual Department Department { get; set; }
public DateTime DateOfBirth { get; set; }
}
I would also recommend that you maintain the List as virtual.

Categories

Resources