Code first One way many to many relationship using data annotation - entity-framework

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;}
}

Related

Accessing a count of a child's child properties

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);

Invalid column when adding a foreginkey

public class PIC
{
[Key]
public int Id { get; set; }
[ForeignKey("IMONumber")]
public int IMONumber { get; set; }
public string VesselName { get; set; }
public string PICOperation { get; set; }
public string PICChartering { get; set; }
}
public class VesselInfo
{
[Key]
public int Id { get; set; }
public string ImoType { get; set; }
public int IMONumber { get; set; }
public PIC PIC { get; set; }
}
When I call following:
var test1 = db.Vessels.ToList();
or
var test2 = db.Vessels.Include(p=>p.PIC).ToList();
I get an error saying PICId invalid column? And opointers?
i will recommend this:
Your PIC class is not connected with a foreign key your VeselInfo table so they are not related and you cannot get information about that. Try replacing your code and try again
public class PIC
{
[Key]
public int Id { get; set; }
public int IMONumber { get; set; }
[ForeignKey("IMONumber")]
public virtual IMON IMON
public string VesselName { get; set; }
public string PICOperation { get; set; }
public string PICChartering { get; set; }
}
public class VesselInfo
{
[Key]
public int Id { get; set; }
public string ImoType { get; set; }
public int IMONumber { get; set; }
public int PicId {get; set;}
[ForeignKey("PicId")]
public virtual PIC PIC { 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.

Code First one to many relationship and category with parent category

public class Category
{
[Key]
public int CategoryId { get; set; }
public int ParentCategoryId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int Status { get; set; }
public virtual ICollection<Category> ParentCategories { get; set; }
public virtual ICollection<ImageSet> ImageSets { get; set; }
[ForeignKey("ParentCategoryId")]
public virtual Category ParentCategory { get; set; }
}
public class ImageSet
{
[Key]
public int ImageSetId { get; set; }
public int CategoryId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string InsertDate { get; set; }
public int Status { get; set; }
public virtual ICollection<Image> Images { get; set; }
[ForeignKey("CategoryId")]
public virtual Category Category { get; set; }
}
public class Image
{
[Key]
public int ImageId { get; set; }
public int ImageSetId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string ImageUrl { get; set; }
public string ThumbImageUrl { get; set; }
public string InsertDate { get; set; }
public int Status { get; set; }
[ForeignKey("ImageSetId")]
public virtual ImageSet ImageSet { get; set; }
}
Context:
public DbSet<Category> Categories { get; set; }
public DbSet<Image> Images { get; set; }
public DbSet<ImageSet> ImageSets { get; set; }
error page:Introducing FOREIGN KEY constraint 'FK_dbo.ImageSets_dbo.Categories_CategoryId' on table 'ImageSets' may
cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or
ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. Could
not create constraint. See previous errors.
Whats the problem?
You need to add this:
modelBuilder.Entity<ImageSet>()
.HasRequired(is => is.Category)
.WithMany(c => c.ImageSets)
.WillCascadeOnDelete(false);
Here are good explanations of why this is happening :
https://stackoverflow.com/a/19390016/1845408
https://stackoverflow.com/a/17127512/1845408

Composite key in table manupulation in Entity Framework

I use Entity Framework 5 Code First and have some problem with composite keys.
I have those tables
And this is how i map the entities
public class Product : EntityBase
{
public Product()
{
this.ProductArticles = new List<ProductArticle>();
}
[Key, Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ProductId { get; set; }
[Key, Column(Order = 1)]
public int PricelistId { get; set; }
public string Description { get; set; }
public string Unit { get; set; }
public string ReportText1 { get; set; }
public string ReportText2 { get; set; }
public bool Standard { get; set; }
public int ProductGroupId { get; set; }
public decimal? Surcharge1 { get; set; }
public decimal? Surcharge2 { get; set; }
public decimal? Surcharge3 { get; set; }
public decimal? Surcharge4 { get; set; }
public decimal PriceMaterialIn { get; set; }
public decimal AdjMaterialIn { get; set; }
public decimal F_PriceMaterialInAdj { get; set; }
public decimal F_AdjMaterial { get; set; }
public decimal F_PriceMaterialOut { get; set; }
public decimal PriceArtisanIn { get; set; }
public decimal F_AdjArtisan { get; set; }
public decimal F_PriceArtisanOut { get; set; }
public decimal F_TotalOut { get; set; }
public decimal F_TotalOutVat { get; set; }
public bool GetPrice { get; set; }
public string Notes { get; set; }
[ForeignKey("ProductGroupId,PricelistId")]
public virtual ProductGroup ProductGroup { get; set; }
[ForeignKey("ProductId,PricelistId")]
public virtual ICollection<ProductArticle> ProductArticles { get; set; }
[ForeignKey("PricelistId")]
public virtual Pricelist Pricelist { get; set; }
}
public class ProductGroup : EntityBase
{
[Key, Column(Order = 0)]
public int ProductGroupId { get; set; }
[Key, Column(Order = 1)]
public int PricelistId { get; set; }
public int OptionalGroupId { get; set; }
public string Prefix { get; set; }
public string Description { get; set; }
public decimal? Surcharge1 { get; set; }
public decimal? Surcharge2 { get; set; }
public decimal? Surcharge3 { get; set; }
public decimal? Surcharge4 { get; set; }
public string ReportText1 { get; set; }
public string ReportText2 { get; set; }
[ForeignKey("OptionalGroupId,PricelistId")]
public virtual OptionalGroup OptionalGroup { get; set; }
[ForeignKey("PricelistId")]
public virtual Pricelist Pricelist { get; set; }
}
But when the context is build i get this message
337,10) : error 3015: Problem in mapping fragments starting at lines
303, 337:Foreign key constraint 'Product_ProductGroup' from table
Product (PricelistId, ProductGroupId) to table ProductGroup
(ProductGroupId, PricelistId):: Insufficient mapping: Foreign key must
be mapped to some AssociationSet or EntitySets participating in a
foreign key association on the conceptual side.
I solved it by redesign the table. Think that composite key are bad design.