Entity Framework Core 7.0 with postgresql [duplicate] - c#

I have an order entity, inside it contains several entities Customer, Store and others, but Entity Framework does not fill those entities. I thought the relationships were wrong but I can't find why the entity framework does not map the entities within orders.
Orders and Customers entities:
public partial class Orders
{
public Orders()
{
OrderItems = new HashSet<OrderItems>();
}
public int OrderId { get; set; }
public int? CustomerId { get; set; }
public byte OrderStatus { get; set; }
public DateTime OrderDate { get; set; }
public DateTime RequiredDate { get; set; }
public DateTime? ShippedDate { get; set; }
public int StoreId { get; set; }
public int StaffId { get; set; }
public virtual Customers Customer { get; set; }
public virtual Staffs Staff { get; set; }
public virtual Stores Store { get; set; }
public virtual ICollection<OrderItems> OrderItems { get; set; }
}
public partial class Customers
{
public Customers()
{
Orders = new HashSet<Orders>();
}
public int CustomerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
public virtual ICollection<Orders> Orders { get; set; }
}
Entity Framework code fragment:
modelBuilder.Entity<Orders>(entity =>
{
entity.HasKey(e => e.OrderId)
.HasName("PK__orders__46596229F9C56686");
entity.ToTable("orders", "sales");
entity.Property(e => e.OrderId).HasColumnName("order_id");
entity.Property(e => e.CustomerId).HasColumnName("customer_id");
entity.Property(e => e.OrderDate)
.HasColumnName("order_date")
.HasColumnType("date");
entity.Property(e => e.OrderStatus).HasColumnName("order_status");
entity.Property(e => e.RequiredDate)
.HasColumnName("required_date")
.HasColumnType("date");
entity.Property(e => e.ShippedDate)
.HasColumnName("shipped_date")
.HasColumnType("date");
entity.Property(e => e.StaffId).HasColumnName("staff_id");
entity.Property(e => e.StoreId).HasColumnName("store_id");
entity.HasOne(d => d.Customer)
.WithMany(p => p.Orders)
.HasForeignKey(d => d.CustomerId)
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("FK__orders__customer__0F4872E8");
entity.HasOne(d => d.Staff)
.WithMany(p => p.Orders)
.HasForeignKey(d => d.StaffId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK__orders__staff_id__1130BB5A");
entity.HasOne(d => d.Store)
.WithMany(p => p.Orders)
.HasForeignKey(d => d.StoreId)
.HasConstraintName("FK__orders__store_id__103C9721");
});
Controller code:
Response in Postman:

One of the options is to eager load them via Include:
return await _context.Orders
.Include(o => o.Customer)
.Include(o => o.Staff)
.Include(o => o.Store)
.ToListAsync()
For more info and options please check out the "Loading Related Data" doc.

Related

EF Core Include a view

I have the following relationships:
public class File
{
public string Path { get; set; }
}
public class Company
{
public string Name { get; set; }
}
public class Account
{
public int CompanyId { get; set; }
public Company Company { get; set; }
public int FileId { get; set; }
public File Avatar { get; set; }
}
public class Subject
{
public int AttachmentId { get; set; }
public File Attachment { get; set; }
}
public class Collaboration
{
public int SenderId { get; set; }
public Account Sender { get; set; }
public int ReceiverId { get; set; }
public Account Receiver { get; set; }
public int SubjectId { get; set; }
public Subject Subject { get; set; }
}
And I end up with this query
_dataContext
.Collaborations
.AsNoTracking()
.Include(x => x.Sender)
.ThenInclude(x => x.Company)
.Include(x => x.Sender)
.ThenInclude(x => x.Avatar)
.Include(x => x.Receiver)
.ThenInclude(x => x.Company)
.Include(x => x.Receiver)
.ThenInclude(x => x.Avatar)
.Include(x => x.Subject)
.ThenInclude(x => x.Attachment);
I'd like to know if it is possible to replace some of the Include / ThenInclude by a view using EF Core.
And if possible use it as
.Include(x => x.SenderAndCompanyInfo)
First create a sql view;
create view SenderAndCompany as
select s.Id,s.Name, s.SurName,c.CompanyName
from Sender s inner join Company c on c.Id = s.CompanyId
After creating sql view create model for it
public class SenderAndCompany
{
public int Id { get; set; }
public string Name { get; set; }
public string SurName { get; set; }
public string CompanyName { get; set; }
}
//Add to context
public DbSet<SenderAndCompany> SenderAndCompany { get; set; }
//map entity to view within the DbContext.OnModelCreating method
modelBuilder
.Entity<SenderAndCompany>()
.ToView(nameof(SenderAndCompany))
.HasKey(t => t.Id);
//Finally
_dataContext
.Collaborations
.AsNoTracking()
.Include(x => x.Sender)
.ThenInclude(x => x.SenderAndCompany)
.Include(x => x.Receiver)
.ThenInclude(x => x.Avatar)
.Include(x => x.Subject)
.ThenInclude(x => x.Attachment);

The association between entities (with the key value, CreatedById:200) has been severed - Error

While I try to delete a ProjectParticipant object from a Project object and call context.SaveChangesAsync(), I get this error:
ERROR: The association between entities ‘employee’ and ‘project’ with the key value ,CreatedById:200 has been severed but the relationship is either marked as ‘required’ or is implicitly required because the foreign key is not billable of the dependent/child entity should be deleted when a required relationship is severed, then setup the relationship to use cascade deletes.
Could someone help me fix this?
Project.cs
public class Project
{
public Project()
{
ProjectParticipants = new HashSet<ProjectParticipant>();
}
public int Id { get; set; }
public int CreatedById { get; set; }
public Employee CreatedBy { get; set; }
public virtual ICollection<ProjectParticipant> ProjectParticipants { get; set; }
}
}
Employee.cs
public class Employee
{
public Employee()
{
Projects = new HashSet<Project>();
ProjectParticipants = new HashSet<ProjectParticipant>();
}
public int Id { get; set; }
public virtual ICollection<Project> Projects { get; set; }
public virtual ICollection<ProjectParticipant> ProjectParticipants { get; set; }
}
ProjectParticipant.cs
public class ProjectParticipant
{
public ProjectParticipant()
{
}
public int Id { get; set; }
public int ProjectId { get; set; }
public virtual Project Project { get; set; }
public int EmployeeId { get; set; }
public virtual Employee Employee { get; set; }
}
ProjectDBContext.cs
public class ProjectDBContext:DBContext
{
public override OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Project>(entity => {
...
entity.HasOne(d => d.CreatedBy)
.WithMany(a => a.Projects)
.HasForeignKey(d => d.CreatedById)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_Project_Employee_CreatedBy");
...
});
modelBuilder.Entity<ProjectParticipant>(entity => {
...
entity.HasOne(d => d.Employee)
.WithMany(a => a.ProjectParticipants)
.HasForeignKey(d => d.EmployeeId)
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("FK_ProjectParticipants_Employee");
entity.HasOne(d => d.Project)
.WithMany(a => a.ProjectParticipants)
.HasForeignKey(d => d.ProjectId)
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("FK_ProjectParticipants_Project");
...
});
modelBuilder.Entity<Employee>(entity => {
...
});
}
}

Cannot create a relationship between Employee and StateProvince

I have an initial class Employee with two properties StateOfEmployment, SecondaryStateOfEmployment of the same entity which is StateProvince.
I'm having this error:
{​​​​​​"Cannot create a relationship between 'StateProvince.Employee'
and 'Employee.SecondaryStateProvinceOfEmployment', because there
already is a relationship between 'StateProvince.Employee' and
'Employee.StateProvinceOfEmployment'. Navigation properties can only
participate in a single relationship."}​​​​​​
My class
public partial class Employee
{
public long EmployeeId { get; set; }
public string JobTitle { get; set; }
public string EmployeeCode { get; set; }
public long? CountryOfEmploymentId { get; set; }
public long? StateProvinceOfEmploymentId { get; set; }
public long? SecondaryStateProvinceOfEmploymentId { get; set; }
public string CostCenter { get; set; }
public DateTime StartEffDate { get; set; }
public DateTime CreatedTimestamp { get; set; }
public string CreatedUser { get; set; }
public DateTime UpdatedTimestamp { get; set; }
public string UpdatedUser { get; set; }
public bool IsDeleted { get; set; }
public long ClientId { get; set; }
public long PersonId { get; set; }
public string CityOfEmployment { get; set; }
public DateTime? HireDate { get; set; }
public string BusinessUnit { get; set; }
public string ManagerName { get; set; }
public string ManagerEmail { get; set; }
public long? EmploymentStatusId { get; set; }
public long? EmploymentTypeId { get; set; }
public string EmploymentTypeClientString { get; set; }
public string HomeLegalEntity { get; set; }
public bool Executive { get; set; }
public string JobLevel { get; set; }
public DateTime SysStartTime { get; set; }
public DateTime SysEndTime { get; set; }
public virtual Client Client { get; set; }
public virtual Country CountryOfEmployment { get; set; }
public virtual EmploymentStatus EmploymentStatus { get; set; }
public virtual EmploymentType EmploymentType { get; set; }
public virtual Person Person { get; set; }
public virtual StateProvince StateProvinceOfEmployment { get; set; }
public virtual StateProvince SecondaryStateProvinceOfEmployment { get; set; }
}
And my context is
modelBuilder.Entity<Employee>(entity =>
{
entity.Property(e => e.BusinessUnit).HasMaxLength(100);
entity.Property(e => e.CityOfEmployment).HasMaxLength(100);
entity.Property(e => e.CostCenter).HasMaxLength(100);
entity.Property(e => e.CreatedTimestamp).HasDefaultValueSql("(getutcdate())");
entity.Property(e => e.CreatedUser)
.IsRequired()
.HasMaxLength(100)
.HasDefaultValueSql("(suser_sname())");
entity.Property(e => e.EmployeeCode).HasMaxLength(100);
entity.Property(e => e.EmploymentTypeClientString).HasMaxLength(100);
entity.Property(e => e.HomeLegalEntity).HasMaxLength(100);
entity.Property(e => e.JobTitle).HasMaxLength(100);
entity.Property(e => e.ManagerEmail).HasMaxLength(100);
entity.Property(e => e.ManagerName).HasMaxLength(200);
entity.Property(e => e.UpdatedTimestamp).HasDefaultValueSql("(getutcdate())");
entity.Property(e => e.UpdatedUser)
.IsRequired()
.HasMaxLength(100)
.HasDefaultValueSql("(suser_sname())");
entity.HasOne(d => d.Client)
.WithMany(p => p.Employee)
.HasForeignKey(d => d.ClientId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_Employee_Client");
entity.HasOne(d => d.CountryOfEmployment)
.WithMany(p => p.Employee)
.HasForeignKey(d => d.CountryOfEmploymentId)
.HasConstraintName("Fk_Employee_CountryId");
entity.HasOne(d => d.EmploymentStatus)
.WithMany(p => p.Employee)
.HasForeignKey(d => d.EmploymentStatusId)
.HasConstraintName("Fk_Employee_EmploymentStatusId");
entity.HasOne(d => d.EmploymentType)
.WithMany(p => p.Employee)
.HasForeignKey(d => d.EmploymentTypeId)
.HasConstraintName("Fk_Employee_EmploymentTypeId");
entity.HasOne(d => d.Person)
.WithMany(p => p.Employee)
.HasForeignKey(d => d.PersonId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_Employee_Person");
entity.HasOne(d => d.StateProvinceOfEmployment)
.WithMany(p => p.Employee)
.HasForeignKey(d => d.StateProvinceOfEmploymentId)
.HasConstraintName("Fk_Employee_StateProvinceId");
entity.HasOne(d => d.SecondaryStateProvinceOfEmployment)
.WithMany(p => p.Employee)
.HasForeignKey(d => d.SecondaryStateProvinceOfEmploymentId)
.HasConstraintName("Fk_Employee_SecondaryStateProvinceId");
});
What am I doing wrong? Thank you.
Use DataAnnotations such as ForeignKey attribute, if you use it you don't need to add any code to the OnModelCreate method:
[Table("Employee")]
public partial class Employee
{
[Key]
public long EmployeeId { get; set; }
[Column("JobTitle")]
public string JobTitle { get; set; }
[Column("EmployeeCode")]
public string EmployeeCode { get; set; }
[Column("CountryOfEmploymentId")]
[ForeignKey("CountryOfEmployment")]
public long? CountryOfEmploymentId { get; set; }
[Column("StateProvinceOfEmploymentId")]
[ForeignKey("StateProvinceOfEmployment")]
public long? StateProvinceOfEmploymentId { get; set; }
[Column("SecondaryStateProvinceOfEmploymentId")]
[ForeignKey("SecondaryStateProvinceOfEmployment")]
public long? SecondaryStateProvinceOfEmploymentId { get; set; }
[Column("CostCenter")]
public string CostCenter { get; set; }
[Column("StartEffDate")]
public DateTime StartEffDate { get; set; }
[Column("CreatedTimestamp")]
public DateTime CreatedTimestamp { get; set; }
[Column("CreatedUser")]
public string CreatedUser { get; set; }
[Column("UpdatedTimestamp")]
public DateTime UpdatedTimestamp { get; set; }
[Column("UpdatedUser")]
public string UpdatedUser { get; set; }
[Column("IsDeleted")]
public bool IsDeleted { get; set; }
[Column("ClientId")]
public long ClientId { get; set; }
[Column("PersonId")]
public long PersonId { get; set; }
[Column("CityOfEmployment")]
public string CityOfEmployment { get; set; }
[Column("HireDate")]
public DateTime? HireDate { get; set; }
[Column("BusinessUnit")]
public string BusinessUnit { get; set; }
[Column("ManagerName")]
public string ManagerName { get; set; }
[Column("ManagerEmail")]
public string ManagerEmail { get; set; }
[Column("EmploymentStatusId")]
public long? EmploymentStatusId { get; set; }
[Column("EmploymentTypeId")]
public long? EmploymentTypeId { get; set; }
[Column("EmploymentTypeClientString")]
public string EmploymentTypeClientString { get; set; }
[Column("HomeLegalEntity")]
public string HomeLegalEntity { get; set; }
[Column("Executive")]
public bool Executive { get; set; }
[Column("JobLevel")]
public string JobLevel { get; set; }
[Column("SysStartTime")]
public DateTime SysStartTime { get; set; }
[Column("SysEndTime")]
public DateTime SysEndTime { get; set; }
[IgnoreDataMember]
public virtual Client Client { get; set; }
[IgnoreDataMember]
public virtual Country CountryOfEmployment { get; set; }
[IgnoreDataMember]
public virtual EmploymentStatus EmploymentStatus { get; set; }
[IgnoreDataMember]
public virtual EmploymentType EmploymentType { get; set; }
[IgnoreDataMember]
public virtual Person Person { get; set; }
[IgnoreDataMember]
public virtual StateProvince StateProvinceOfEmployment { get; set; }
[IgnoreDataMember]
public virtual StateProvince SecondaryStateProvinceOfEmployment { get; set; }
}
Below should work,
entity.HasOne(d => d.SecondaryStateProvinceOfEmployment)
.WithMany(p => p.Employee)
.HasForeignKey(d => d.SecondaryStateProvinceOfEmploymentId)
.HasConstraintName("Fk_Employee_SecondaryStateProvinceId").OnDelete(DeleteBehavior.Restrict);

Entity Framework Core Multiple sub objects Include / ThenInclude

I'm having trouble including all the entities when using EF to query. Using dummy labels, my DB has a structure of a Family which contains a Collection of Person objects, and a House. Each Person object has a Wallet associated with them, with the Wallet having a Driver's License object. The House has three objects: a Ktichen, Den, and Garage. My Models were set up with a DB-first approach and I can provide them if need be.
But I'm having a 'Lambda expression used inside Include is not valid.' error when running this code:
public Family GetFamily(int familyId)
{
DBContext context = new DBContext();
Family family= context.Family.Where(fam=> fam.Id== famId)
.Include(fam => fam.PersonCollection)
.ThenInclude(p => p.Wallet)
.ThenInclude(w => w.License)
.Include(fam => fam.House)
.ThenInclude(h => h.Kitchen)
.Include(fam => fam.House)
.ThenInclude(h => h.Den)
.Include(fam => fam.House)
.ThenInclude(h => h.Garage)
.First();
return family
}
If I comment out the includes for the License, and two of the three rooms in the house, it runs, but otherwise it does not.
Here are all the Models
public partial class Family
{
public Family()
{
PersonCollection = new HashSet<PersonCollection>();
}
public int HouseId { get; set; }
public virtual House House { get; set; }
public virtual ICollection<PersonCollection> PersonCollection { get; set; }
}
public partial class House
{
public House()
{
Family = new HashSet<Family>();
Den = new HashSet<Den>();
}
public int Id { get; set; }
public byte KitchenId { get; set; }
public int? DenId { get; set; }
public int? GarageId { get; set; }
public virtual Kitchen Kitchen { get; set; }
public virtual Garage GarageNavigation { get; set; }
public virtual Den DenNavigation { get; set; }
public virtual ICollection<Family> Family{ get; set; }
public virtual ICollection<Den> Den { get; set; }
}
public partial class Kitchen
{
public Kitchen()
{
House = new HashSet<House>();
}
public byte Id { get; set; }
public virtual ICollection<House> House { get; set; }
}
public partial class Garage
{
public Garage()
{
House = new HashSet<House>();
}
public int Id { get; set; }
public virtual ICollection<House> House { get; set; }
}
public partial class Den
{
public Den()
{
House = new HashSet<House>();
}
public int Id { get; set; }
public virtual ICollection<House> House { get; set; }
}
public partial class Person
{
public int FamilyId{ get; set; }
public int? WalletId { get; set; }
public virtual Wallet Wallet { get; set; }
public virtual Family Family { get; set; }
}
public partial class Wallet
{
public Wallet()
{
PersonCollection = new HashSet<Person>();
}
public int Id { get; set; }
public int? DenId { get; set; }
public virtual License License { get; set; }
public virtual ICollection<Person> PersonCollection { get; set; }
}
public partial class License
{
public License()
{
Wallet = new HashSet<Wallet>();
}
public int Id { get; set; }
public virtual ICollection<Wallet> Wallet { get; set; }
}
Here's the Model Builders. I had to rename and delete a lot of things to simplify and obfuscate our code, but hopefully I kept everything that's relevant.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Family>(entity =>
{
entity.HasOne(d => d.House)
.WithMany(p => p.Family)
.HasForeignKey(d => d.FamilyId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_Family_House");
});
modelBuilder.Entity<Person>(entity =>
{
entity.HasOne(d => d.Wallet)
.WithMany(p => p.Person)
.HasForeignKey(d => d.WalletId)
.HasConstraintName("FK_Person_Wallet");
entity.HasOne(d => d.Family)
.WithMany(p => p.Person)
.HasForeignKey(d => new { d.FamilyId })
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_Person_Family");
});
modelBuilder.Entity<Wallet>(entity =>
{
entity.HasOne(d => d.LicenseNavigation)
.WithMany(p => p.Wallet)
.HasForeignKey(d => d.License)
.HasConstraintName("FK_Wallet_License");
});
modelBuilder.Entity<License>(entity =>
{
entity.ToTable("License", "DBO");
});
modelBuilder.Entity<House>(entity =>
{
entity.HasOne(d => d.Kitchen)
.WithMany(p => p.House)
.HasForeignKey(d => d.KitchenId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_House_Kitchen");
entity.HasOne(d => d.GarageNavigation)
.WithMany(p => p.House)
.HasForeignKey(d => d.Garage)
.HasConstraintName("FK_House_Garage");
entity.HasOne(d => d.DenNavigation)
.WithMany(p => p.House)
.HasForeignKey(d => d.Garage)
.HasConstraintName("FK_House_Garage");
});
modelBuilder.Entity<Kitchen>(entity =>
{
entity.Property(e => e.Id).ValueGeneratedOnAdd();
});
modelBuilder.Entity<Garage>(entity =>
{
entity.Property(e => e.Description)
.IsRequired()
.HasMaxLength(50);
});
modelBuilder.Entity<Den>(entity =>
{
entity.ToTable("Den", "DBO");
entity.Property(e => e.Description)
.IsRequired()
.HasMaxLength(100)
.IsUnicode(false);
});
}

Why does the entity framework not map the customer entity in my order?

I have an order entity, inside it contains several entities Customer, Store and others, but Entity Framework does not fill those entities. I thought the relationships were wrong but I can't find why the entity framework does not map the entities within orders.
Orders and Customers entities:
public partial class Orders
{
public Orders()
{
OrderItems = new HashSet<OrderItems>();
}
public int OrderId { get; set; }
public int? CustomerId { get; set; }
public byte OrderStatus { get; set; }
public DateTime OrderDate { get; set; }
public DateTime RequiredDate { get; set; }
public DateTime? ShippedDate { get; set; }
public int StoreId { get; set; }
public int StaffId { get; set; }
public virtual Customers Customer { get; set; }
public virtual Staffs Staff { get; set; }
public virtual Stores Store { get; set; }
public virtual ICollection<OrderItems> OrderItems { get; set; }
}
public partial class Customers
{
public Customers()
{
Orders = new HashSet<Orders>();
}
public int CustomerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
public string ZipCode { get; set; }
public virtual ICollection<Orders> Orders { get; set; }
}
Entity Framework code fragment:
modelBuilder.Entity<Orders>(entity =>
{
entity.HasKey(e => e.OrderId)
.HasName("PK__orders__46596229F9C56686");
entity.ToTable("orders", "sales");
entity.Property(e => e.OrderId).HasColumnName("order_id");
entity.Property(e => e.CustomerId).HasColumnName("customer_id");
entity.Property(e => e.OrderDate)
.HasColumnName("order_date")
.HasColumnType("date");
entity.Property(e => e.OrderStatus).HasColumnName("order_status");
entity.Property(e => e.RequiredDate)
.HasColumnName("required_date")
.HasColumnType("date");
entity.Property(e => e.ShippedDate)
.HasColumnName("shipped_date")
.HasColumnType("date");
entity.Property(e => e.StaffId).HasColumnName("staff_id");
entity.Property(e => e.StoreId).HasColumnName("store_id");
entity.HasOne(d => d.Customer)
.WithMany(p => p.Orders)
.HasForeignKey(d => d.CustomerId)
.OnDelete(DeleteBehavior.Cascade)
.HasConstraintName("FK__orders__customer__0F4872E8");
entity.HasOne(d => d.Staff)
.WithMany(p => p.Orders)
.HasForeignKey(d => d.StaffId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK__orders__staff_id__1130BB5A");
entity.HasOne(d => d.Store)
.WithMany(p => p.Orders)
.HasForeignKey(d => d.StoreId)
.HasConstraintName("FK__orders__store_id__103C9721");
});
Controller code:
Response in Postman:
One of the options is to eager load them via Include:
return await _context.Orders
.Include(o => o.Customer)
.Include(o => o.Staff)
.Include(o => o.Store)
.ToListAsync()
For more info and options please check out the "Loading Related Data" doc.

Categories