Why does EF.core sometimes includes invalid columns? - tsql

How does EF.Core choose it's columns?
I have these two simple classes: Payment and Site
I use this for my select list:
var payments = db.Payments
.Include(e => e.Site)
.AsNoTracking();
EF.Core generates this invalid sql:
SELECT [e].[pay_id], [e].[amount], [e].[cheque_no], [e].[client_id], [e].[dt], [e].[last_modified], [e].[last_modified_by], [e].[pay_dt], [e].[pay_mode], [e].[site_id], [e.Site].[site_id], [e.Site].[address], [e.Site].[client_id], [e.Site].[last_modified], [e.Site].[last_modified_by], [e.Site].[name], [e.Site].[state]
FROM [Payments] AS [e]
INNER JOIN [Sites] AS [e.Site] ON [e].[site_id] = [e.Site].[site_id]
ORDER BY [e.Site].[name]
There is no client_id in the Payments table or Payment class below
public class Payment
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Int32 pay_id { get; set; }
public DateTime? dt { get; set; }
public Int32 site_id { get; set; }
public Decimal? amount { get; set; }
public DateTime? pay_dt { get; set; }
public String pay_mode { get; set; }
public String cheque_no { get; set; }
public virtual Site Site { get; set; }
public DateTime? last_modified { get; set; }
public int? last_modified_by { get; set; }
}
public class Site
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Int32 site_id { get; set; }
public String name { get; set; }
public Int32 client_id { get; set; }
public String address { get; set; }
public String state { get; set; }
public virtual Client Client { get; set; }
public List<Deployment> Deployments { get; set; }
public List<Contract> Contracts { get; set; }
public List<Timesheet> Timesheets { get; set; }
public DateTime? last_modified { get; set; }
public int? last_modified_by { get; set; }
}

Related

How to get EF.core to use LEFT JOINs instead of INNER JOINs

I'm trying to include foreign-key details as part of my query.
How can I get EF.core to use LEFT JOINs instead of INNER JOINs?
public class Offence
{
[Key]
public Int32 offence_id { get; set; }
public Int32 guard_id { get; set; }
public Int32 penalty_id { get; set; }
public DateTime? dt_recorded { get; set; }
public Int32 salary_id { get; set; }
public Decimal? amount { get; set; }
public String status { get; set; }
public Int32 site_id { get; set; }
public Guard Guard { get; set; }
public Salary Salary { get; set; }
public Site Site { get; set; }
public Penalty Penalty { get; set; }
public DateTime? last_modified { get; set; }
public int? last_modified_by { get; set; }
}
In Controller GetList
var offences = db.Offences
.Include(e => e.Guard)
.Include(e => e.Penalty)
.Include(e => e.Site)
.Include(e => e.Salary)
.AsNoTracking();
Generated SQL:
SELECT [e].[offence_id], [e].[amount], [e].[dt_recorded], [e].[guard_id], [e].[last_modified], [e].[last_modified_by], [e].[penalty_id], [e].[salary_id], [e].[site_id], [e].[status], [e.Salary].[salary_id], [e.Salary].[dt_paid], [e.Salary].[guard_id], [e.Salary].[last_modified], [e.Salary].[last_modified_by], [e.Salary].[period], [e.Site].[site_id], [e.Site].[address], [e.Site].[client_id], [e.Site].[last_modified], [e.Site].[last_modified_by], [e.Site].[name], [e.Site].[state], [e.Penalty].[penalty_id], [e.Penalty].[amount], [e.Penalty].[description], [e.Penalty].[dt], [e.Penalty].[last_modified], [e.Penalty].[last_modified_by], [e.Penalty].[name], [e.Guard].[guard_id], [e.Guard].[address], [e.Guard].[bank], [e.Guard].[dob], [e.Guard].[dt_joined], [e.Guard].[dt_trained], [e.Guard].[has_picture], [e.Guard].[height], [e.Guard].[last_modified], [e.Guard].[last_modified_by], [e.Guard].[location_id], [e.Guard].[marital_status], [e.Guard].[mobiles], [e.Guard].[name], [e.Guard].[nuban], [e.Guard].[ref_no], [e.Guard].[religion], [e.Guard].[salary], [e.Guard].[sex], [e.Guard].[state_origin], [e.Guard].[status]
FROM [Offences] AS [e]
left JOIN [Salaries] AS [e.Salary] ON [e].[salary_id] = [e.Salary].[salary_id]
left JOIN [Sites] AS [e.Site] ON [e].[site_id] = [e.Site].[site_id]
left JOIN [Penalties] AS [e.Penalty] ON [e].[penalty_id] = [e.Penalty].[penalty_id]
left JOIN [Guards] AS [e.Guard] ON [e].[guard_id] = [e.Guard].[guard_id]
ORDER BY [e.Guard].[name]
Found the solution, make all the foreign keys null-able, then EF.core uses a LEFT JOIN for the query instead:
public class Offence
{
[Key]
public Int32 offence_id { get; set; }
public Int32? guard_id { get; set; } // make null-able
public Int32? penalty_id { get; set; } // make null-able
public DateTime? dt_recorded { get; set; }
public Int32? salary_id { get; set; } // make null-able
public Decimal? amount { get; set; }
public String status { get; set; }
public Int32? site_id { get; set; } // make null-able
public Guard Guard { get; set; }
public Salary Salary { get; set; }
public Site Site { get; set; }
public Penalty Penalty { get; set; }
public DateTime? last_modified { get; set; }
public int? last_modified_by { get; set; }
}

EF 6 Mapping Complex Composite Keys

I have the following models
public class Company
{
[Key, Column(Order=0)]
public int Id {get;set;}
public string CompanyCode { get; set; }
public string Name { get; set; }
public virtual ICollection<Account> Accounts { get; set; }
public virtual ICollection<Journal> Journals { get; set; }
}
public class Account
{
[Key, Column(Order=0)]
public int Id { get; set; }
[Key, Column(Order=1), ForeignKey("Company")]
public int CompanyId { get; set; }
public int GLAccountNumber { get; set; }
public decimal Balance { get; set; }
public virtual Company Company { get; set; }
public virtual ICollection<Journal> Journals { get; set; }
}
public class Journal
{
[Key, Column(Order=0)]
public int Id { get; set; }
[Key, Column(Order=1), ForeignKey("Company")]
public int CompanyId { get; set; }
[ForeignKey("Account")]
public int AccountId { get; set; }
public DateTime EntryDate { get; set; }
public decimal Amount { get; set; }
public virtual Company Company { get; set; }
public virtual Account Account { get; set; }
}
How would I map the relationship between these models, Specifically I cannot figure out how to define the Composite Key in the Journal Model to map to Account By CompanyId, AccountId
You could use fluent APi (my personal preference - clear and less error prone):
modelBuilder.Entity<Journal>()
.HasRequired(e => e.Account)
.WithMany(e => e.Journals)
.HasForeignKey(e => new { e.AccountId, e.CompanyId });
But if you prefer data annotations, then apply the ForeignKey attribute on the navigation property and specify comma separated list of the FK properties:
public class Journal
{
[Key, Column(Order=0)]
public int Id { get; set; }
[Key, Column(Order=1)]
public int CompanyId { get; set; }
public int AccountId { get; set; }
public DateTime EntryDate { get; set; }
public decimal Amount { get; set; }
[ForeignKey("CompanyId")]
public virtual Company Company { get; set; }
[ForeignKey("AccountId,CompanyId")]
public virtual Account Account { get; set; }
}

Error in creating a controller file

I am using Entity Framework. I have tried everything, searching and adding keys but Ienter image description here cannot understand what the problem is and how to resolve it.
public class Reservation
{
[Key]
public int BookingID { get; set; }
public int CustomerID { get; set; }
public int RoomID { get; set; }
public string BookingDate { get; set; }
public int Check_In { get; set; }
public int Check_Out { get; set; }
public int Adults { get; set; }
public int Children { get; set; }
public int NoOfNights { get; set; }
[ForeignKey("RoomID")]
public virtual Room Rooms { get; set; }
[ForeignKey("CustomerID")]
public virtual CustomerDetails CustomerDetail { get; set; }
public virtual ICollection<Payment> Payment { get; set; }
}
public class CustomerDetails
{
[Key]
public int CustomerID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int PostCode { get; set; }
public string State { get; set; }
public int PhoneNumber { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public virtual ICollection<Reservation> Reservations { get; set; }
}
enter image description here
All tables need a primary key or you can't use Entity Framework.

What kind of relationship do I need

I am stuck on figuring this out. MVC 5, EntityFramework
My project revolves around a Job. Every Job has multiple ChangeOrders. I have that setup fine. A Job has one Customer. That works fine as well. my problem is with the Customer Employees. The Customer class has a one-to-many relationship with the CustomerEmployee class. Every Customer Employee has a basic properties plus a Role property. Super,PM,Accountant, or Admin. Well when I create a job, I need to select a CustomerEmployee Admin/PM etc...
What relationship would this be? A many-to-many relationship? In my mind, the Job class would need to have a CustomerEmployeeSuperId, CustomerEmployeePMId, CustomerEmployeeAdminId and CustomerEmployeeAccountantId.
Because right now all it has is CustomerEmployeeId
How do I do this?
Current Setup
public class Job
{
//job
public int JobId { get; set; }
public int? JobNumber { get; set; }
public string JobName { get; set; }
public string JobDescription { get; set; }
public int? GeoAreaId { get; set; }
public virtual JobMisc.GeoArea GeoArea { get; set; }
public int? JobClassId { get; set; }
public virtual JobMisc.JobClass JobClass { get; set; }
public int? JobTypeId { get; set; }
public virtual JobMisc.JobType JobType { get; set; }
public Int64? CustomerId { get; set; }
public virtual Customer Customer { get; set; }
public virtual ICollection<ChangeOrder> ChangeOrders { get; set; }
public virtual ICollection<PurchaseOrder> PurchaseOrders { get; set; }
public int? CustomerEmployeeId { get; set; }
public virtual ICollection<CustomerEmployee> CustomerEmployees { get; set; }
}
public class Customer
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.None)]
public Int64 CustomerId { get; set; }
public string CustomerName { get; set; }
public Int64? CustomerPhoneNumber { get; set; }
public Int64? CustomerFaxNumber { get; set; }
public string CustomerAddress { get; set; }
public string CustomerCity { get; set; }
public string CustomerState { get; set; }
public int? CustomerZipcode { get; set; }
public string CustomerWebsite { get; set; }
public string CustomerOtherShit { get; set; }
public bool? CustomerIsHidden { get; set; }
public virtual ICollection<CustomerEmployee> CustomerEmployees { get; set; }
public List<Job> Jobs { get; set; }
}
public class CustomerEmployee
{
[Key]
public int CustomerEmployeeId { get; set; }
public string CustomerEmployeeFirstName { get; set; }
public string CustomerEmployeeLastName { get; set; }
public string CustomerEmployeeEmail { get; set; }
public Int64? CustomerEmployeePhoneNumber { get; set; }
public Int64? CustomerEmployeeCellNumber { get; set; }
public Int64? CustomerEmployeeFaxNumber { get; set; }
public bool? CustomerEmployeeIsHidden { get; set; }
public string CustomerEmployeeRole { get; set; }
public Int64? CustomerId { get; set; }
public virtual Customer Customer { get; set; }
public int? JobId { get; set; }
public virtual ICollection<Job> Jobs { get; set; }
}
Well, for the individual job, it would be a one to many relationship. For multiple jobs, it could be many to many.
Is it possible that an employee who is an Admin might also be pressed into service as a tester for certain jobs?
I'd recommend created a child table for JobRoles, one that links to the JobID, a CustomerEmployeeID, and a JobRoleID (assuming the possibility of the JobRoles being flexible).
Hope this helps...

how to get student courses with entity framework

I have 2 classes, course and student, and I want to get student courses with student id
help me please
I'm using entity framework code first
public class Course {
public int CourseID { get; set; }
public string Title { get; set; }
public string Details { get; set; }
public string img { get; set; }
public DateTime DateAdded { get; set; }
public Guid UserAddID { get; set; }
public Guid userEditID { get; set; }
public int SubCategoryID { get; set; }
public string Code { get; set; }
public string Summury { get; set; }
public decimal Price { get; set; }
public bool IsGift { get; set; }
public DateTime DateUpdated { get; set; }
public bool DelFlag { get; set; }
public DateTime? DelDate { get; set; }
public Guid? UserDelID { get; set; }
public ICollection<Student> Students { get; set; }
}
public class Student {
[Key]
public int StudentID { get; set; }
public string Name { get; set; }
public DateTime? DateBirth { get; set; }
public int? Age { get; set; }
public int? Sex { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Mobile { get; set; }
public string Mobile2 { get; set; }
public string UniversityID { get; set; }
public string CollegeID { get; set; }
public string IdentityID { get; set; }
public string Address { get; set; }
public string Education { get; set; }
public decimal? Payments { get; set; }
public string HowToKnow { get; set; }
public DateTime? GradeDate { get; set; }
public string LaterCourses { get; set; }
public string Job { get; set; }
public string Specialist { get; set; }
public string Notes { get; set; }
public int StatueID { get; set; }
public Guid? UserID { get; set; }
public DateTime? DateAdded { get; set; }
public Guid UserAddID { get; set; }
public Guid userEditID { get; set; }
public DateTime DateUpdated { get; set; }
public bool DelFlag { get; set; }
public DateTime? DelDate { get; set; }
public Guid? UserDelID { get; set; }
public virtual IList<Course> Courses { get; set; }
}
I want to get all courses for a given StudentID using a lambda expression.
var students = repository.Query<Course>(c => c.Student.Any(st=>st.StudentID == StudentID)