Entity Framework relationship between another fields than id - entity-framework

I have two class (tables)
Person { id(primary key) , code, name, address, ...}
Order {id(primary key) , order_number, customer, create_date, description, ...}
I want to create relationship between Person.code and Order.customer (one two many).
How can I create that relationship in EF code first.

OK it has an easy solution
[Table("Person")]
public partial class Person
{
public long ID { get; set; }
[Key()]
[StringLength(10)]
public string code { get; set; }
[StringLength(100)]
public string name { get; set; }
[Column(TypeName = "text")]
public string address{ get; set; }
public ICollection<Order> Orders { get; set; }
}
and for order
[Table("Order")]
public partial class Order
{
public long ID { get; set; }
public int order_number { get; set; }
[StringLength(10)]
public string customer { get; set; }
[Column(TypeName = "text")]
public string description { get; set; }
//...
[ForeignKey("customer")]
public Library Person { get; set; }
}
I will create a new question about specification various composite keys per each navigation property.

Related

Issue with Include in Entity framework

I have Employee, Address and Organization classes. below are the details
public partial class Employees
{
public Employees()
{
AddressDetails = new HashSet<AddressDetails>();
OrganizationDetails = new HashSet<OrganizationDetails>();
}
public string Id { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public ICollection<AddressDetails> AddressDetails { get; set; }
public ICollection<OrganizationDetails> OrganizationDetails { get; set; }
}
public partial class AddressDetails
{
public int Id { get; set; }
public string Address { get; set; }
public string Type { get; set; }
public string EmployeeId { get; set; }
public Employees Employee { get; set; }
}
public partial class OrganizationDetails
{
public int Id { get; set; }
public string Name { get; set; }
public string Location { get; set; }
public string EmployeeId { get; set; }
public Employees Employee { get; set; }
}
I have used fully defined relationship, you can see Employee has collections of both AddressDetails and OrganizationDetails as navigation properties. And each of them have EmployeeId and Employee in the same way.
My problem is, when i try to fetch Employee details using Include(), both AddressDetails and OrganizationDetails are loaded that's fine, but when i checked both the collections each entity has again loaded Employee information and so on.
for example: if i check AddressDetails collection which is loaded, Address object has information of Employee and again that Employee has collections of both AddressDetails and OrganizationDetails.
Please help me how can i avoid this. I don't want to remove Employee object property from AddressDetails and OrganizationDetails. is there anyway to make it work with Include().
here is the query i'm using to load these navigation properties.
List employees = _context.Employees.Include(emp => emp.AddressDetails).Include(emp => emp.OrganizationDetails).ToList();

EF Core code first Inheritance of separate table

Say I have a table Company defined in following entity:
public class Company
{
public Guid CompanyId { get; set; }
[Required]
public string Name { get; set; }
[MaxLength(50)]
public string Uid { get; set; }
...
}
And I need another table CompanyHistory what will have all fields of Company extended with CompanyHistoryId, EffectiveDate, DEffectiveDate.
I have tried it like this:
public class CompanyHistory : Company
{
public Guid CompanyHistoryId { get; set; }
public virtual Company { get; set; }
}
But instead of 2 tables migration makes one and combines all the columns.
How can I get same result without writing all the column again as is done here:
public class CompanyHistory
{
public Guid CompanyHistoryId { get; set; }
public Guid CompanyId { get; set; }
public virtual Company Company { get; set; }
[Required]
public string Name { get; set; }
[MaxLength(50)]
public string Uid { get; set; }
...
}

How do i create One-to-One mapping in EF 6 using Data Annotation approach

I am using EF 6.1.1.
I am unable to figure out how to create One-to-One relationship between two classes/tables with both entities have their owns PKs. I originally posted question link but could not get much help on it OR i am not able to get it. So, here i am putting my question in simple way.
Appreciate if someone can share thoughts on it.
My Requirement:
I would like create One-To-One relationship between Principle and Dependant with 'Id' from Principle class acts as Foreign Key in dependant class.
Principle Class
public class Student
{
public string FullName {get; set;}
}
Dependant Class
public class StudentReport
{
public string RollNumber { get; set; }
public string StudentType { get; set; }
}
Add PKs – EF requires this:
public class Student
{
public int Id { get; set; }
public string FullName { get; set; }
}
public class StudentReport
{
public int Id { get; set; }
public string RollNumber { get; set; }
public string StudentType { get; set; }
}
Note that EF 5 and later supports naming conventions: Id indicates a primary key. Alternately, it also supports the name of the class followed by "Id", so the above keys could have been StudentId for Student and StudentReportId for StudentReport, if you wished.
Add the foreign relation as a navigation property to at least one of the tables – in this case, you stated that StudentReport is the dependent, so let's add it to that one:
public class Student
{
public int Id { get; set; }
public string FullName { get; set; }
}
public class StudentReport
{
public int Id { get; set; }
public string RollNumber { get; set; }
public string StudentType { get; set; }
public Student Student { get; set; }
}
Again – by naming convention – EF determines that a single Student property on StudentReport indicates that this is a navigational property associated with a foreign key. (By defining only the Student property, but no foreign key property, you are indicating that you don't care what EF names the associated FK ... basically, you're indicating you'll always access the related Student via the property.)
If you did care about the name of the FK property, you could add it:
public class Student
{
public int Id { get; set; }
public string FullName { get; set; }
}
public class StudentReport
{
public int Id { get; set; }
public string RollNumber { get; set; }
public string StudentType { get; set; }
public int StudentId { get; set; }
public Student Student { get; set; }
}
Again – by naming convention – EF determines that StudentId is the FK associated with the Student property because it has the class name, "Student", followed by "Id".
All of this, so far, has been using conventions as defined in Entity Framework Code First Conventions, but Data Annotations are also an option, if you wish:
public class Student
{
[Key]
public int Id { get; set; }
public string FullName { get; set; }
}
public class StudentReport
{
[Key]
public int Id { get; set; }
public string RollNumber { get; set; }
public string StudentType { get; set; }
[ForeignKey("Student")]
public int StudentId { get; set; }
public Student Student { get; set; }
}
Doing this is actually a good idea, because it makes clearer your intent to other programmers that might not be aware of EF Conventions – but can easily infer them from simply looking at EF Data Annotations – and is still less cumbersome than Fluent API.
UPDATE
I just realized, I left this as a one-to-many, with enforcement of the one-to-one relationship being left to do in the code using this model. To enforce the one-to-one in the model, you could add a navigation property to the Student class going the other way:
public class Student
{
public int Id { get; set; }
public string FullName { get; set; }
public StudentReport StudentReport { get; set; }
}
public class StudentReport
{
public int Id { get; set; }
public string RollNumber { get; set; }
public string StudentType { get; set; }
public Student Student { get; set; }
}
However, that's going to break, because EF doesn't know which entity to insert first on an add. To indicate which is dependent, you have to specific that the dependent class' PK is the FK to the principal class (this enforces one-to-one because – in order for a Student/StudentReport pair to be associated – their Id properties must be the exact same value):
public class Student
{
public int Id { get; set; }
public string FullName { get; set; }
public StudentReport StudentReport { get; set; }
}
public class StudentReport
{
[ForeignKey("Student")]
public int Id { get; set; }
public string RollNumber { get; set; }
public string StudentType { get; set; }
public Student Student { get; set; }
}
or, using the full set of Data Annotations from earlier:
public class Student
{
[Key]
public int Id { get; set; }
public string FullName { get; set; }
public StudentReport StudentReport { get; set; }
}
public class StudentReport
{
[Key, ForeignKey("Student")]
public int Id { get; set; }
public string RollNumber { get; set; }
public string StudentType { get; set; }
public Student Student { get; set; }
}

Mapping Many to many in Entity framework

simply I ask this How to Map , How to ProductCustomer in the sample ??
public class ProductCustomer
{
public virtual Product Product { get; set; }
public virtual Customer Customer { get; set; }
}
and about Product and Customer :
public class Customer
{
public int Id { get; set; }
public string CustomerName { get; set; }
}
public class Product
{
public int Id { get; set; }
public string ProductName { get; set; }
public decimal Amount { get; set; }
}
thanks!
You don't need to create the ProductCustomer object.
In EF, you create your Customer and Product, and then you create collections to each. This will automatically create the proper link tables.
public class Customer
{
public int Id { get; set; }
public string CustomerName { get; set; }
public virtual List<Product> Products {get;set;}
}
public class Product
{
public int Id { get; set; }
public string ProductName { get; set; }
public decimal Amount { get; set; }
public virtual List<Customer> Customers {get;set;}
}
This is only the case, however, if your link table has no payload (has no additional data). If it does, then you will need to create the link table as an entity similar to what you originally did, but you add 1:many links in your product and customer classes to the link entity. You then have to modify your queries to query through the link table.

Entity Framework/MVC4 - Relation with multiple column key

I am new to EF and am having trouble figuring how to set up relationship between my main table Investors, with contact information, and a table Notes which can have many notes per investor. Here are the models:
public class Investor
{
public int Id { get; set; }
public string Name { get; set; }
public string Company { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Cell { get; set; }
public string Fax { get; set; }
[Display(Name="Address 1")]
public string Address1 { get; set; }
[Display(Name = "Address 2")]
public string Address2 { get; set; }
public string City { get; set; }
[StringLength(2, ErrorMessage = "State must be 2 characters")]
public string State { get; set; }
public string Zip { get; set; }
public string ContactTableId { get; set; }
[ForeignKey("ContactTableId, ContactId")]
public virtual List<Note> Notes { get; set; }
}
public class Note
{
[Key]
[Column(Order = 0)]
public string ContactTableId { get; set; }
[Key]
[Column(Order = 1)]
public int? ContactId { get; set; }
public string note { get; set; }
public DateTime? DateCreated { get; set; }
}
My attempt as setting this up, as above, generated the error 'The number of properties in the Dependent and Principal Roles in a relationship constraint must be identical.' on the statement:
public ActionResult Index()
{
return View(db.Investors.ToList());
}
in the controller. How do I set this up to make it pull the Notes automagically.
The foreign key is not "ContactTableId, ContactId", it is the single field Investor_Id in table Note (or Notes). EF thinks you try to map the single key to two field and coins this somewhat elusive exception message. But just remove the ForeignKey attribute and EF will use the foreign key field in Note.