Accessing a count of a child's child properties - entity-framework

I have a three classes District, PostalCode and Premise. District contains a virtual list of postalcodes and the postal code class contains a virtual list of premises, from within the district controller is there any was of calculating the number of premises which are in the district, classes as follows:
public class District
{
[Key]
public int DistrictID { get; set; }
public string Name { get; set; }
public int Households { get; set; }
public int Population { get; set; }
public virtual List<PostalCode> PostalCodes { get; set; }
}
public class PostalCode
{
[Key]
public int PostalCodeID { get; set; }
public string FullPostcode { get; set; }
public bool InUse { get; set; }
public decimal Latitude { get; set; }
public decimal Longitude { get; set; }
public int Easting { get; set; }
public int Northing { get; set; }
public string GridReference { get; set; }
public string Ward { get; set; }
public string Parish { get; set; }
[Display(Name = "Introduced")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime Introduced { get; set; }
[Display(Name = "Terminated")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? Terminated { get; set; }
public int Altitude { get; set; }
public string Country { get; set; }
[Display(Name = "Last Updated")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? LastUpdated { get; set; }
public string Quality { get; set; }
public string LSOACode { get; set; }
public bool Processed { get; set; }
[Display(Name = "Last Visited")]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? LastVisited { get; set; }
public string SalesRep { get; set; }
public virtual List<Premise> Premises { get; set; }
public int? DistrictID { get; set; }
public virtual District District { get; set; }
}
public class Premise
{
[Key]
public int PremiseID { get; set; }
public string MPRN { get; set; }
public string MeterPointAddress { get; set; }
public string DUoSGroup { get; set; }
public string MeterConfigurationCode { get; set; }
public string MeterPointStatus { get; set; }
public int PostalCodeID { get; set; }
public virtual PostalCode PostalCode { get; set; }
public bool Live { get; set; }
public bool Pending { get; set; }
}
I am able to access the list of postal codes within the view of the district controller by using the following code:
#item.PostalCodes.Count()
I thought that I may have been able to use #item.PostalCodes.All().Premises.Count() or some variation of that but this is not being allowed by the compiler, is there any way that this can be accessing the third level premises class from within the district controller?

You can use Include and 2 foreach loops for this. Take a look at this article
public class Customer
{
public int CustomerID { get; set; }
public string Name { get; set; }
public virtual List<Invoice> Invoices { get; set; }
}
public class Invoice
{
public int InvoiceID { get; set; }
public DateTime Date { get; set; }
public int CustomerID { get; set; }
public virtual Customer Customer { get; set; }
public virtual ICollection<Item> Items { get; set; }
}
public class Item
{
public int ItemID { get; set; }
public string Name { get; set; }
public int InvoiceID { get; set; }
public virtual Invoice Invoice { get; set; }
}
And get data:
using (var context = new MyContext())
{
var list = context.Customers.ToList();
foreach (var customer in list)
{
Console.WriteLine("Customer Name: {0}", customer.Name);
foreach (var customerInvoice in customer.Invoices)
{
var items=customerInvoice.Items.Tolist();
}
}
}

Create a partial class District and add a couple field to this partial class:
public partial class District
{
[NotMapped]
public int PostaCodeCount
[NotMapped]
public int PremissesCount
}
Try this query inside of your controller:
var rowDistricts=db.Districts
.Include(pc=>pc.PostalCodes)
.ThenInclude(pr => pr.Premisses)
.ToList();
var districts= new List<District>();
foreach (var item in rowDistricts)
{
item.PostalCodeCount=item.PostalCodes.Count();
item.PremissesCount=item.Premisses.Count();
item.Premisses=null;
item.PostalCodes=null;
districts.Add(item);
}
return View(districts);

Related

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.

Including multiple child layers in LINQ to SQL

I have a data model which has three layers as follows:
Market Message
MessageType598
Metered Generation Information
The classes are as follows:
[Table("MarketMessage")]
public partial class MarketMessage
{
public MarketMessage()
{
messageType300 = new HashSet<messageType300>();
messageType300S = new HashSet<messageType300S>();
messageType300W = new HashSet<messageType300W>();
messageType305 = new HashSet<messageType305>();
messageType310 = new HashSet<messageType310>();
messageType310W = new HashSet<messageType310W>();
messageType320 = new HashSet<messageType320>();
messageType320W = new HashSet<messageType320W>();
messageType332 = new HashSet<messageType332>();
messageType332W = new HashSet<messageType332W>();
messageType591 = new HashSet<messageType591>();
messageType594 = new HashSet<messageType594>();
messageType595 = new HashSet<messageType595>();
messageType596 = new HashSet<messageType596>();
messageType597 = new HashSet<messageType597>();
messageType598 = new HashSet<messageType598>();
}
public int MarketMessageID { get; set; }
public DateTime CreatedOn { get; set; }
[Required]
[StringLength(4)]
public string messageType { get; set; }
[Required]
[StringLength(8)]
public string VersionNumber { get; set; }
public DateTime MarketTimestamp { get; set; }
[Required]
[StringLength(35)]
public string TxRefNbr { get; set; }
[Required]
[StringLength(3)]
public string Sender { get; set; }
[Required]
[StringLength(3)]
public string Recipient { get; set; }
[StringLength(10)]
public string alertFlag { get; set; }
[StringLength(50)]
public string fileName { get; set; }
public bool IsDeleted { get; set; }
public virtual ICollection<messageType300> messageType300 { get; set; }
public virtual ICollection<messageType300S> messageType300S { get; set; }
public virtual ICollection<messageType300W> messageType300W { get; set; }
public virtual ICollection<messageType305> messageType305 { get; set; }
public virtual ICollection<messageType310> messageType310 { get; set; }
public virtual ICollection<messageType310W> messageType310W { get; set; }
public virtual ICollection<messageType320> messageType320 { get; set; }
public virtual ICollection<messageType320W> messageType320W { get; set; }
public virtual ICollection<messageType332> messageType332 { get; set; }
public virtual ICollection<messageType332W> messageType332W { get; set; }
public virtual ICollection<messageType591> messageType591 { get; set; }
public virtual ICollection<messageType594> messageType594 { get; set; }
public virtual ICollection<messageType595> messageType595 { get; set; }
public virtual ICollection<messageType596> messageType596 { get; set; }
public virtual ICollection<messageType597> messageType597 { get; set; }
public virtual ICollection<messageType598> messageType598 { get; set; }
}
public partial class messageType598
{
public int messageType598ID { get; set; }
public int MarketMessageID { get; set; }
public DateTime SettlementDate { get; set; }
public int SettlementRunIndicator { get; set; }
[Required]
[StringLength(9)]
public string GenerationUnit { get; set; }
}
[Table("MeteredGenerationInformation")]
public partial class MeteredGenerationInformation
{
[Key]
public int MeteredGenerationInfoID { get; set; }
public DateTime IntervalPeriodTimestamp { get; set; }
public int SettlementInterval { get; set; }
public decimal GenerationUnitMeteredGeneration { get; set; }
public decimal LossAdjustedGenerationUnitMeteredGeneration { get; set; }
public int? MessageType594ID { get; set; }
public int? MessageType598ID { get; set; }
}
I am attempting to join a list of all market messages received of type 598 including the metered generation information but I am unsure how to do this via LINQ to SQL. I have attempted the following:
var list598s = db.MarketMessage.Where(mm => mm.messageType == "598")
.Include(mm => mm.messageType598)
.ToList();
This includes the market messages including the 598 information but how can I include the metered generation information also in this list, I would also ideally like to refine the list based on a date field found within the messageType598 level
As a SQL query I would write the following:
select * from MarketMessage as a
inner join messageType598 as b on a.MarketMessageID = b.MarketMessageID
inner join MeteredGenerationInformation as c on b.messageType598ID = c.messageType598ID
where c.IntervalPeriodTimestamp between '1 aug 2016' and '31 aug 2016'

Code first One way many to many relationship using data annotation

I have two models in my application: Stock and Report. A report can have many stocks and a stock can be used in many reports.
public enum ElectionType
{
MANAGER =1 ,
INSPECTOR ,
BOTH
}
public class Report
{
public Report()
{
Stocks = new List<Stock>();
}
public int ReportID { get; set; }
[Required]
public DateTime ShamsiDate { get; set; }
public int? StockID { get; set; }
[Required]
public ElectionType ElectionType { get; set; }
[ForeignKey("StockID")]
public virtual ICollection<Stock> Stocks { get; set;}
}
public class Stock
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int StockID { get; set; }
public int FinancialCode { get; set; }
public String NationalCode { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
public String FatherName { get; set; }
public String Place { get; set; }
public int StockCount { get; set; }
public int StockPrice { get; set; }
public int StockSize { get; set; }
public int StartStock { get; set; }
public int EndStock { get; set; }
}
I want to create a one way relationship so there is no way to access a Report from a Stock. I have written this code but it doesn't work.
To do it with annotations you will need a junction table:
public class ReportStock
{
[Key, Column(Order = 1)]
public int ReportID { get; set; }
[Key, Column(Order = 2)]
public int StockID { get; set; }
[ForeignKey("ReportID")]
public virtual Report Report { get; set;}
[ForeignKey("StockID")]
public virtual Stock Stock { get; set;}
}
Then change your Report class:
public class Report
{
public Report()
{
ReportStocks = new List<ReportStock>();
}
public int ReportID { get; set; }
[Required]
public DateTime ShamsiDate { get; set; }
[Required]
public ElectionType ElectionType { get; set; }
public virtual ICollection<ReportStock> ReportStocks { get; set;}
}

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)

EntityFramework get related item by id or field

I have two objects like:
public class Area : IEntity
{
public virtual int Id { get; set; }
public virtual int AreaTypeLookupId { get; set; }
[Column(TypeName = "varchar")]
[StringLength(100)]
public virtual string Name { get; set; }
[Column(TypeName = "varchar")]
[StringLength(2)]
public virtual string VMRegionCode { get; set; }
public virtual int GISPrimaryKeyId { get; set; }
public virtual string ConcatenatedGISAreaIds { get; set; }
public virtual int? ParentAreaId { get; set; }
public virtual int? ParentRegionAreaId { get; set; }
[Column(TypeName = "char")]
[StringLength(3)]
public virtual string CostCenterCode { get; set; }
[Column(TypeName = "varchar")]
[StringLength(64)]
public string CreatedByUserName { get; set; }
public DateTime CreatedDateTime { get; set; }
[Column(TypeName = "varchar")]
[StringLength(64)]
public string LastModifiedByUserName { get; set; }
public DateTime? LastModifiedDateTime { get; set; }
// Navigation properties
public virtual AreaTypeLookup AreaTypeLookup { get; set; }
}
public class AreaTypeLookup : IEntity
{
[Column("Id")]
public virtual int AreaTypeLookupId { get; set; }
[Column(TypeName = "varchar")]
[StringLength(100)]
public virtual string Name { get; set; }
[Column(TypeName = "varchar")]
[StringLength(10)]
public virtual string ShortName { get; set; }
public virtual int? AreaTypeLevelLookupId { get; set; }
public virtual int? OperationTypeLookupId { get; set; }
public virtual int? ParentAreaTypeLookupId { get; set; }
public bool IsAvailableToSetBudgetAgainst { get; set; }
public int DisplaySortOrder { get; set; }
public bool IsProtected { get; set; }
public DateTime? DeletedDateTime { get; set; }
public int? ManagedByServiceTypeLookupId { get; set; }
[Column(TypeName = "varchar")]
[StringLength(64)]
public string CreatedByUserName { get; set; }
public DateTime CreatedDateTime { get; set; }
[Column(TypeName = "varchar")]
[StringLength(64)]
public string LastModifiedByUserName { get; set; }
public DateTime? LastModifiedDateTime { get; set; }
}
What I want is to get all the areas where areatypelookupid = 3. For this area type the name is "region"
What is the best way to get the areas for code maintainability:
This:
var areas = _unitOfWork.AreaRepository.GetAll().Where(x => x.AreaTypeLookupId == 3);
or this:
var areas = _unitOfWork.AreaRepository.GetAll().Where(x => x.AreaTypeLookup.Name == "region");
where I guess "region" should really becoming from a resources file.
Typically, you will want to use the primary key as that should be immutable. However, if you can guarantee that the lookup name is not going to change, then searching by name would be tolerable. The reason I say tolerable is because running queries off of the primary key will be more efficient on the database, on top of the immutability.