SQL to Entity Framework, inner SELECT with multiple JOINs - c#

I have the following SQL query that I need to rewrite to Entity Framework with navigation properties. Basically, and Employee has a number of tasks that someone can volunteer to do. I'm trying to find all employees that have at least one volunteer assigned to any task.
SELECT j.noTasks, e.*
FROM Employee e
LEFT JOIN
(SELECT e.id, COUNT(vt.TaskId) as "noTasks"
FROM Employee e
LEFT JOIN Task t on e.id = t.EmployeeId
LEFT JOIN VolunteerTask vt on vt.TaskId = t.id
GROUP BY e.id) j
ON e.id = j.id AND noTasks > 0
The troubling part is the inner SELECT. I've read the documentation, but I'm having difficulties understanding it.
Employee class:
public partial class Employee : IEntity
{
public int id { get; set; }
[Required]
[StringLength(100)]
public string Name { get; set; }
[StringLength(100)]
public string WorkPlace { get; set; }
public int EmployeeTypeId { get; set; }
[Required]
[StringLength(11)]
public string OrganizationNumber { get; set; }
[StringLength(20)]
public string Telephone { get; set; }
[Required]
[StringLength(100)]
public string StreetAddress { get; set; }
[StringLength(200)]
public string CoAddress { get; set; }
[Required]
[StringLength(20)]
public string ZipCode { get; set; }
[StringLength(200)]
public string City { get; set; }
[StringLength(200)]
public string HomePage { get; set; }
[Required]
[StringLength(200)]
public string ContactPerson { get; set; }
[StringLength(30)]
public string ContactPhone { get; set; }
[StringLength(30)]
public string ContactPhone2 { get; set; }
[StringLength(200)]
public string ContactEmailAddress { get; set; }
public DateTime RegisteredDate { get; set; }
public virtual EmployeeType EmployeeType { get; set; }
[Required]
public UserStatus Status { get; set; }
public string ImageFileName { get; set; }
}
Task class:
public partial class Task : IEntity
{
public Task()
{
VoluntaryTasks = new HashSet<VoluntaryTask>();
TaskInterest = new HashSet<TaskInterest>();
TaskCalendarItems = new HashSet<TaskCalendarItem>();
}
public int id { get; set; }
[StringLength(100)]
public string Name { get; set; }
public int EmployeeId { get; set; }
public int AreaId { get; set; }
[Column(TypeName = "ntext")]
public string Description { get; set; }
public int NoOfVolunteers { get; set; }
public DateTime? StartDate { get; set; }
public DateTime? PublicationDate { get; set; }
public DateTime EndDate { get; set; }
[Required]
[StringLength(200)]
public string ContactPerson { get; set; }
[Required]
[StringLength(30)]
public string ContactTelephone { get; set; }
[StringLength(30)]
public string ContactTelephone2 { get; set; }
[StringLength(100)]
public string EmailAddress { get; set; }
public bool isPublished { get; set; }
public bool NotificationMailSent { get; set; }
public double? Latitude { get; set; }
public double? Longitude { get; set; }
public int Priority { get; set; }
public RecordStatus RecordStatus { get; set; }
public virtual Area Area { get; set; }
public string LocationDescription {get; set;}
public virtual Employee Employee { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<VoluntaryTask> VoluntaryTasks { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<TaskInterest> TaskInterest { get; set; }
public virtual ICollection<TaskLanguageSkill> TaskLanguageSkills { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<TaskCalendarItem> TaskCalendarItems { get; set; }
}
VoluntaryTask class:
public partial class VoluntaryTask
{
//[Key]
[Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int VoluntaryId { get; set; }
//[Key]
[Column(Order = 1)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int TaskId { get; set; }
//[Key]
public VoluntaryTaskStatus Status { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public virtual Task Task { get; set; }
public virtual Voluntary Voluntary { get; set; }
}

Related

EF CORE understanding relationships in a Gym setting

Ok I am kinda stuck I need a ef query that will get me the following data.
I have sessions which are created at the Gym I am using ef core here so
In the main grid I need to list the students that our their for the workout that day.
ID
Session Name
Start Date
TeamId
1
Test 1
06/11/2021
1
---
2
Test 2
05/11/2021
2
---
I have table Students which has a team Id
ID
FirstName
Last Name
TeamId
1
Matt
Smith
1
---
2
Martha
Jones
2
---
Team Includes the students and is linked back to the Student via Team Id
ID
Name
Session Id
1
Test Team
1
!2
Test Team 2
2
For Example what I want to be able to do is Pick the session that is on the start date of the 5 and display only the students attending that day.
My Poco Class for Session
public class Session
{
public int Id { get; set; }
public string? Name { get; set; }
public int OccuranceType { get; set; }
public int? StaffId { get; set; }
public int? Day { get; set; }
public int? Duration { get; set; }
public DateTime? StartDate { get; set; }
public DateTime? EndDate { get; set; }
public int? Status { get; set; }
public int? TeamId { get; set; }
public Team? Team { get; set; }
public bool? IsDeleted { get; set; }
public bool? IsActive { get; set; }
public string? CreatedBy { get; set; }
public string? LastModifiedBy { get; set; }
public DateTime? LastUpdatedDate { get; set; }
public DateTime? CreatedDate { get; set; }
}
Student
public class Student
{
public int Id { get; set; }
public int? Type { get; set; }
public int? CoachId { get; set; }
public virtual Coach Coach { get; set; }
public int? TeamId { get; set; }
public virtual Team Team { get; set; }
public string? FirstName { get; set; }
public string? Surname { get; set; }
public DateTime? DOB { get; set; }
public decimal? Weight { get; set; }
public decimal? Height { get; set; }
public int? Gender { get; set; }
public string? Photo { get; set; }
public int? Age { get; set; }
public string? AddressLine1 { get; set; }
public string? AddressLine2 { get; set; }
public string? State { get; set; }
public string? ZipCode { get; set; }
public string? Mobile { get; set; }
public string? EmailAddress { get; set; }
public ICollection<ConditioningWorkout> ConditioningWorkouts { get; set; }
public ConditioningWorkout? ConditioningWorkout { get; set; }
public ICollection<Booking> Bookings { get; set; }
public ICollection<BikeWorkOut> BikeWorkOuts { get; set; }
public bool? IsDeleted { get; set; }
public ICollection<Notes>? Notes { get; set; }
public decimal? TB { get; set; }
public decimal? OP { get; set; }
public decimal? PU { get; set; }
public decimal? PB { get; set; }
public decimal? BP { get; set; }
public int Status { get; set; }
public bool? IsActive { get; set; }
public string? CreatedBy { get; set; }
public string? LastModifiedBy { get; set; }
public DateTime? LastUpdatedDate { get; set; }
public DateTime? CreatedDate { get; set; }
}
Team
public class Team
{
public int Id { get; set; }
public Guid? UserId { get; set; }
public Guid? TennantId { get; set; }
public string Name { get; set; }
public int? CoachId { get; set; }
public virtual Coach Coach { get; set; }
public ICollection<Student> Students { get; set;}
public bool? IsDeleted { get; set; }
public int? SessionId { get; set; }
public bool? IsActive { get; set; }
public string? CreatedBy { get; set; }
public string? LastModifiedBy { get; set; }
public DateTime? LastUpdatedDate { get; set; }
public DateTime? CreatedDate { get; set; }
}
I think I need to have some link back from the Student to the session but because they can block book sessions and team level I dont no how to achieve this.
It looks like a Session has a Team(s?) and a Team has a Student(s), so it's reasonably straight forward:
context.Sessions.Include(s => s.Team).ThenInclude(t => t.Students)
.Where(s => s.StartDate == new DateTime(2021, 11, 5))
This gets you a collections of sessions that should have their Team property populated with a Team, and in turn that Team has a Students collection that is populated with Students

How to get data from 3 related entities using LINQ?

I have a student class, program class and session class. I want to select a student on the basis of his rollno, sessionName, programName and password.
program and session classes have one to many relationship with student class.
This is Session Class.
public class Session
{
[Key]
public int SessionID { get; set; }
[Required]
[MaxLength(30)]
public string SessionName { get; set; }
//Relationship ------- Navigational Properties -------------------------------
public virtual List<Student> Students { get; set; }
public virtual List<Teacher> Teachers { get; set; }
public virtual List<Subject> Subjects { get; set; }
public virtual List<Program> Programs { get; set; }
}
This is program class.
public class Program
{
[Key]
public int ProgramID { get; set; }
[Required]
[MaxLength(30)]
public string ProgramName { get; set; }
//Relationship ------- Navigational Properties -------------------------------
public virtual List<Student> Students { get; set; }
public virtual List<Teacher> Teachers { get; set; }
public virtual List<Subject> Subjects { get; set; }
}
And this is Student Class.
public class Student
{
[Key]
[Column(Order = 0)]
public int StudentID { get; set; }
[Required]
[MaxLength(30)]
public string FirstName { get; set; }
[Required]
[MaxLength(30)]
public string LastName { get; set; }
[Required]
[MaxLength(30)]
public string UserName { get; set; }
[Required]
[MaxLength(35)]
public string Email { get; set; }
[Required]
[MaxLength(30)]
public string Password { get; set; }
[Required]
[MaxLength(30)]
public string FatherName { get; set; }
[Required]
public DateTime DOB { get; set; }
[Required]
[MaxLength(15)]
public string CNIC { get; set; }
[Required]
public int RollNo { get; set; }
public bool Active { get; set; }
public bool Graduated { get; set; }
public bool Expelled { get; set; }
//Relationship ------- Navigational Properties -------------------------------
public virtual List<Teacher> Teachers { get; set; }
public virtual List<Subject> Subjects { get; set; }
public virtual List<StudentMessage> Messages { get; set; }
public Session Session { get; set; }
public Program Program { get; set; }
public Grade Grade { get; set; }
public Attendance Attendance { get; set; }
public StudentContact StudentContact { get; set; }
public StudentMessage StudentMessage { get; set; }
}
Now how do I select student's username who has given specific rollno, sessionName, programName, password using LINQ Query Syntax and using LINQ Method syntax?
In database, Student Table contains SessionID and ProgramID.
I know "Join" is used to extract data from multiple tables but i don't know how to use it in LINQ Syntax.
You can use following code:
var list = dbContext.Students
.Where(e=>e.RollNo == 10)
.Where(e=>e.Password == "password")
.Where(e=>e.Session.SessionName == "SessionName")
.Where(e=>e.Session.ProgramName == "ProgramName")
.Select(e=> e.UserName)
.ToList();

Cycles or multiple cascade paths

I have the following datamodel and its associated model classes. I have been removing dependencies to get it right, but I keep on getting this error.
Datamodel
I can't find out why there is a cascading path in the model. I am afraid I will not be able to reduce the dependencies.
Model Classes
public class DataFormat
{
public int DataFormatID { get; set; }
[Display (Name = "Data Format Name")]
[Remote("DuplicateFormatName", "DataFormats", HttpMethod = "POST", ErrorMessage = "Data Format Name already Exists")]
public string FormatName { get; set; }
[Display (Name = "Data Format Type")]
public string FormatType { get; set; }
[Display (Name = "Precision Digits")]
public string PrecisionDigits { get; set; }
[Display (Name = "Scaling Digits")]
public string ScalingDigits { get; set; }
[Display (Name = "Description in German")]
public string DescriptionDE { get; set; }
[Display (Name = "Description in English")]
public string DescriptionEN { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime ModifiedOn { get; set; }
public string CreatedBy { get; set;}
public string ModifiedBy { get; set; }
public virtual ICollection<TcSet> TcSets { get; set; }
}
public class Lsystem
{
public int LsystemID { get; set; }
[Display (Name = "System Name") ]
[Remote("DuplicateSystemName", "Lsystems", HttpMethod = "POST", ErrorMessage = "System Name already Exists")]
public string LsystemName { get; set; }
[Display (Name = "Material Number")]
public string MaterialNumber { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime ModifiedOn { get; set; }
public string CreatedBy { get; set; }
public string ModifiedBy { get; set; }
[Display(Name = "Description in English")]
public string DescriptionEN { get; set; }
[Display(Name = "Description in German")]
public string DescriptionDE { get; set; }
public int LsystemFamilyID { get; set; }
public virtual LsystemFamily LsystemFamily { get; set; }
public virtual ICollection<Option> Options { get; set; }
}
public class LsystemFamily
{
public int LsystemFamilyID { get; set; }
[Display (Name = "Family Name")]
[Remote("DuplicateFamilyName","LsystemFamilies",HttpMethod = "POST",ErrorMessage= "System Family Name already Exists")]
public string FamilyName { get; set; }
public int LsystemCount { get; set; }
[Display ( Name = "Description in English")]
public string DescriptionEN { get; set; }
[Display (Name = "Description in German")]
public string DescriptionDE { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime ModifiedOn { get; set; }
public string CreatedBy { get; set; }
public string ModifiedBy { get; set; }
public virtual ICollection<Lsystem> Lsystems { get; set; }
}
public class Option
{
public int OptionID { get; set;}
[Display (Name = "Option Type")]
public string OptionName { get; set; }
[Display (Name ="Description in English")]
public string DescriptionEN { get; set; }
[Display(Name = "Description in German")]
public string DescriptionDE { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime ModifiedOn { get; set; }
public string CreatedBy { get; set; }
public string ModifiedBy { get; set; }
public int TechnicalCharacteristicID { get; set; }
public int LsystemID { get; set; }
public virtual ICollection<OptionValue> OptionValues { get; set; }
public virtual TechnicalCharacteristic TechnicalCharacteristic { get; set; }
public virtual Lsystem Lsystem { get; set; }
// public virtual ICollection< SetValue> SetValue { get; set; }
}
public class OptionValue
{
public int OptionValueID { get; set; }
[Display(Name = "Option Value")]
public string OptionVal { get; set; }
public int OptionID { get; set; }
// public int SetValueID { get; set; }
public virtual Option Option { get; set; }
public virtual ICollection< SetValue> SetValue { get; set; }
}
public class SetValue
{
public int SetValueID { get; set; }
[Display(Name = "Value")]
public string Value { get; set; }
[Display(Name="Internal")]
public bool Status { get; set; }
//public int LsystemID { get; set; }
//public int OptionID { get; set; }
public int TcSetID { get; set; }
public int OptionValueID { get; set; }
//public virtual Lsystem Lsystem { get; set; }
//public virtual Option Option { get; set; }
public virtual OptionValue OptionValue { get; set; }
public virtual TcSet TcSet { get; set; }
}
public class TcSet
{
public int TcSetID { get; set; }
[Display (Name = "Technical characteristic Property name")]
public string SetName { get; set; }
[Display(Name = "PhysicalUnit")]
public string PhysicalUnit { get; set; }
[Display (Name = "Data Usage")]
public DataUsage DataUsage { get; set; }
[Display (Name = "Data Status")]
public DataStatus DataStatus { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime ModifiedOn { get; set; }
[Display (Name = "Description in German")]
public string DescriptionDE { get; set; }
[Display (Name = "Description in English")]
public string DescriptionEN { get; set; }
public string CreatedBy { get; set; }
public string ModifiedBy { get; set; }
public int TechnicalCharacteristicID { get; set; }
public int DataFormatID { get; set; }
public virtual ICollection<SetValue> SetValues { get; set; }
public virtual DataFormat DataFormat { get; set; }
public virtual TechnicalCharacteristic TechnicalCharacteristic { get; set; }
}
public class TechnicalCharacteristic
{
public int TechnicalCharacteristicID { get; set; }
[Display (Name = "Technical Characteristic Name")]
public string TCName { get; set; }
[Display (Name = "Description in English")]
public string DescriptionEN { get; set; }
[Display (Name = "Description in German")]
public string DescriptionDE { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime ModifiedOn { get; set; }
public string CreatedBy { get; set; }
public string ModifiedBy { get; set; }
public virtual ICollection<TcSet> TcSets { get; set; }
//public virtual ICollection<Option> Options { get; set; }
}
Now my error is between the tables Options and technicalCharacteristics. I had the error previosly with LSystem and SetVal & Options.
What can be the workaround to get the task right?
I have not tried fluent APIs.
Here is another way you can do the same AND have a technicalChareristic to be required. I did this last week with one of my own models. Sorry it toook so long to come up with a reply. (Do the same with the other files.)
In your Context file override the following method...
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Option>()
.HasRequired(x => x.TechnicalCharacteristic)
.WithMany(y => y.Options)
.HasForeignKey(a => a.TechnicalCharacteristicID)
.WillCascadeOnDelete(false);
base.OnModelCreating(modelBuilder);
}
Where the models are...
public class Option
{
public int OptionID { get; set; }
[Display(Name = "Option Type")]
public string OptionName { get; set; }
[Display(Name = "Description in English")]
public string DescriptionEN { get; set; }
[Display(Name = "Description in German")]
public string DescriptionDE { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime ModifiedOn { get; set; }
public string CreatedBy { get; set; }
public string ModifiedBy { get; set; }
public int LsystemID { get; set; }
public virtual ICollection<OptionValue> OptionValues { get; set; }
public int TechnicalCharacteristicID { get; set; }
public virtual TechnicalCharacteristic TechnicalCharacteristic { get; set; }
public virtual Lsystem Lsystem { get; set; }
// public virtual ICollection< SetValue> SetValue { get; set; }
DateTime d = new DateTime();
}
public class TechnicalCharacteristic
{
public int TechnicalCharacteristicID { get; set; }
[Display(Name = "Technical Characteristic Name")]
public string TCName { get; set; }
[Display(Name = "Description in English")]
public string DescriptionEN { get; set; }
[Display(Name = "Description in German")]
public string DescriptionDE { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime ModifiedOn { get; set; }
public string CreatedBy { get; set; }
public string ModifiedBy { get; set; }
public virtual ICollection<TcSet> TcSets { get; set; }
public virtual ICollection<Option> Options { get; set; }
}
I hope this helps.
I believe your error is coming because EntityFramework cannot handle the null state of your TechnicalCharacteristicID in the Option class. If you have no problem in TechnicalCharacteristic being null, do the following in your option class. It should get rid of your error:
public int? TechnicalCharacteristicID { get; set; }
that is, your option class will become...
public class Option
{
public int OptionID { get; set; }
[Display(Name = "Option Type")]
public string OptionName { get; set; }
[Display(Name = "Description in English")]
public string DescriptionEN { get; set; }
[Display(Name = "Description in German")]
public string DescriptionDE { get; set; }
public DateTime CreatedOn { get; set; }
public DateTime ModifiedOn { get; set; }
public string CreatedBy { get; set; }
public string ModifiedBy { get; set; }
public int LsystemID { get; set; }
public virtual ICollection<OptionValue> OptionValues { get; set; }
public int? TechnicalCharacteristicID { get; set; }
public virtual TechnicalCharacteristic TechnicalCharacteristic { get; set; }
public virtual Lsystem Lsystem { get; set; }
// public virtual ICollection< SetValue> SetValue { get; set; }
}
Do the same with other errant tables. I hope this answers your question! Good luck.

join two different list by id into one list

I've got two different list of two different objects. Then i got one list of a viewmodel that contains properties from both the objects and i want them to be joined into that list.
//Product
public string id { get; set; }
public string unitMeasurement { get; set; }
public Nullable<int> minOrderQty { get; set; }
public Nullable<int> packSize { get; set; }
public string leadTime { get; set; }
public Nullable<int> generalAccessoryCategoryId { get; set; }
public string Company { get; set; }
public Nullable<decimal> Weight { get; set; }
public Nullable<int> ProductType { get; set; }
//ProductDescription
public string id { get; set; }
public string language { get; set; }
public string shortDescription { get; set; }
public string detailDescription { get; set; }
public string Name { get; set; }
public Nullable<int> Rank { get; set; }
public Nullable<System.DateTime> StartDate { get; set; }
public Nullable<System.DateTime> EndDate { get; set; }
public class ProductResponse
{
public string id { get; set; }
//Product
public string unitMeasurement { get; set; }
public Nullable<int> minOrderQty { get; set; }
public Nullable<int> packSize { get; set; }
public string leadTime { get; set; }
public Nullable<int> generalAccessoryCategoryId { get; set; }
public string Company { get; set; }
public Nullable<decimal> Weight { get; set; }
public Nullable<int> ProductType { get; set; }
//ProductDescription
public string language { get; set; }
public string shortDescription { get; set; }
public string detailDescription { get; set; }
public string Name { get; set; }
public Nullable<int> Rank { get; set; }
public Nullable<System.DateTime> StartDate { get; set; }
public Nullable<System.DateTime> EndDate { get; set; }
}
So i just want to join a list of products and a list of productdescriptions into a list of productResponse. How can i do this? id of product and productdescription is the same so thats what i want to join them on.
Join them on id and then call ToList:
var productResponses = from p in products
join pd in productDescriptions
on p.id equals pd.id
select new ProductResponse
{
id = p.id,
language = pd.language,
// ...
}
var list = productResponses.ToList();

Complex relationship mappings in entity framework

I am building a reservation system. I have users in roles('admin', 'client', 'employee', 'student').
Each reservation must be associated with a user of role client, it might be assigned to user of role employee and might also be assigned to user of role student.
So in my reservation class I have properties of type User and I have marked them with [ForeignKey("AnytypeId")] attribute to hint EF for relations.
I have seen code like this at http://blog.stevensanderson.com/2011/01/28/mvcscaffolding-one-to-many-relationships/
public class Reservation
{
public int ReservationID
{
get;
set;
}
[Required(ErrorMessage="Please provide a valid date")]
public DateTime ReservationDate
{
get;
set;
}
public DateTime ReservationEnd { get; set; }
public DateTime EntryDate
{
get;
set;
}
public DateTime UpdatedOn
{
get;
set;
}
public decimal Ammount
{
get;
set;
}
public decimal? Discount { get; set; }
[DataType(DataType.MultilineText)]
public string ServiceDetails { get; set; }
[DataType(DataType.MultilineText)]
public string Remarks { get; set; }
public string VoucherNumber { get; set; }
public int ServiceID
{
get;
set;
}
public Service Service
{
get;
set;
}
public string EmployeeId { get; set; }
[ForeignKey("EmployeeId")]
public User Employee { get; set; }
public string ClientId { get; set; }
[ForeignKey("ClientId")]
public User Client { get; set; }
public string StudentId { get; set; }
[ForeignKey("StudentId")]
public User Student { get; set; }
}
public class User
{
//[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
//public Guid UserId { get; set; }
[Key]
[Required(ErrorMessage = "User Name is required")]
[Display(Name = "User Name")]
[MaxLength(100)]
public string UserName { get; set; }
[Required]
[MaxLength(64)]
public byte[] PasswordHash { get; set; }
[Required]
[MaxLength(128)]
public byte[] PasswordSalt { get; set; }
[Required(ErrorMessage = "Email is required")]
[DataType(DataType.EmailAddress)]
[MaxLength(200)]
public string Email { get; set; }
[MaxLength(200)]
public string Comment { get; set; }
[Display(Name = "Approved?")]
public bool IsApproved { get; set; }
[Display(Name = "Crate Date")]
public DateTime DateCreated { get; set; }
[Display(Name = "Last Login Date")]
public DateTime? DateLastLogin { get; set; }
[Display(Name = "Last Activity Date")]
public DateTime? DateLastActivity { get; set; }
[Display(Name = "Last Password Change Date")]
public DateTime DateLastPasswordChange { get; set; }
public string address { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public string Phone { get; set; }
public bool? IsActive { get; set; }
public int? ClientTypeID { get; set; }
public virtual ClientType ClientType { get; set; }
public virtual ICollection<Role> Roles { get; set; }
public DateTime? PackageValidity { get; set; }
public virtual ICollection<Reservation> Reservations { get; set; }
}
public class UserMap : EntityTypeConfiguration<User>
{
public UserMap()
{
this.HasMany(u => u.Roles)
.WithMany(r => r.Users)
.Map(m =>
{
m.ToTable("RoleMemberships");
m.MapLeftKey("Username");
m.MapRightKey("RoleName");
});
}
}
Now as I run my mvc3 EF code first app database created for me on the fly with following ERD and edmx model.
Now few problems that I am having:
1. When I am listing all the users of role clients their reservation property is showing always 0 even if their are reservations available in database.
2. If I am trying to delete a user of role client who have reservation in database I get following error.
The DELETE statement conflicted with the REFERENCE constraint "Reservation_Client". The conflict occurred in database "CRSDB", table "dbo.Reservations", column 'ClientId'.
The statement has been terminated.
I checked the realtions in ERD and edmx model their is no cascade delete applied to them. How can I instruct EF to delete all the reservations when deleting user of role client but not for users of role employee or student.
This code does the trick
public class Reservation
{
public int ReservationID
{
get;
set;
}
[Required(ErrorMessage="Please provide a valid date")]
public DateTime ReservationDate
{
get;
set;
}
public DateTime ReservationEnd { get; set; }
public DateTime EntryDate
{
get;
set;
}
public DateTime UpdatedOn
{
get;
set;
}
public decimal Ammount
{
get;
set;
}
public decimal? Discount { get; set; }
[DataType(DataType.MultilineText)]
public string ServiceDetails { get; set; }
[DataType(DataType.MultilineText)]
public string Remarks { get; set; }
public String PaymentMethod { get; set; }
public string VoucherNumber { get; set; }
public int ServiceID
{
get;
set;
}
public virtual Service Service
{
get;
set;
}
public string EmployeeID { get; set; }
[ForeignKey("EmployeeID")]
public virtual User Employee { get; set; }
public string ClientID { get; set; }
[ForeignKey("ClientID")]
public virtual User Client { get; set; }
public string StudentID { get; set; }
[ForeignKey("StudentID")]
public virtual User Student { get; set; }
}
public class ReservationMap : EntityTypeConfiguration<Reservation>
{
public ReservationMap()
{
this.HasOptional(r => r.Client).WithMany().WillCascadeOnDelete(true);
this.HasOptional(r => r.Employee).WithMany().WillCascadeOnDelete(false);
this.HasOptional(r=>r.Student).WithMany().WillCascadeOnDelete(false);
}
}

Categories

Resources