I've been using this tutorial as a guide for code first n:m. I usually go with db first but for a school project I have to use code first...
My 2 classes are as follows:
public class Product
{
public Product()
{
Stocks = new HashSet<Stock>();
ServingUnits = new HashSet<Unit>();
Orders = new HashSet<Order>();
}
public int ProductId { get; set; }
[StringLength(128, MinimumLength = 1)]
[Required]
public string Title { get; set; }
[StringLength(512, MinimumLength = 1)]
public string Description { get; set; }
public int ExperationPeriod { get; set; }
public byte[] Image { get; set; }
[Required]
public DateTime DateCreated { get; set; }
//foreign keys
[Required]
public int StockUnitId { get; set; }
[Required]
public string CreatedById { get; set; }
[Required]
public int ProductStateId { get; set; }
[Required]
public int ProductTypeId { get; set; }
//navigation properties
[ForeignKey("StockUnitId")]
public virtual Unit StockUnit { get; set; }
[ForeignKey("CreatedById")]
public virtual ApplicationUser CreatedBy { get; set; }
[ForeignKey("ProductStateId")]
public virtual ProductState ProductState { get; set; }
[ForeignKey("ProductTypeId")]
public virtual ProductType ProductType { get; set; }
public virtual ICollection<Stock> Stocks { get; set; }
public virtual ICollection<Unit> ServingUnits { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
and the other:
public class Unit
{
public Unit()
{
Orders = new HashSet<Order>();
ProductsStock = new HashSet<Product>();
ProductsServe = new HashSet<Product>();
}
public int UnitId { get; set; }
[StringLength(255, MinimumLength = 1)]
[Required]
public string Title { get; set; }
[StringLength(128, MinimumLength = 1)]
public string ShortName { get; set; }
public string Description { get; set; }
[Required]
public double BasisFactor { get; set; }
[Required]
public DateTime DateCreated { get; set; }
//foreign keys
[Required]
public string CreatedById { get; set; }
//navigation properties
[ForeignKey("CreatedById")]
public virtual ApplicationUser CreatedBy { get; set; }
public virtual ICollection<Product> ProductsStock { get; set; }
public virtual ICollection<Product> ProductsServe { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
But the join table doesn't exist in my database. Can anyone see what I'm doing wrong?
Thanks
Related
It's a class where i need to add item in Subtasks with Ef Core. Have no idea how to do it. Please help!
public class Do
{
[Key]
public int Id { get; set; }
[Required]
public string Title { get; set; }
[Required]
public string Description { get; set; }
public string Executors { get; set; }
public DoStatus Status { get; set; }
public DateTime Created { get; set; } = DateTime.Now;
[Required]
public int Plan { get; set; }
public int Fact { get; set; }
public DateTime? Finished { get; set; }
public virtual ICollection<Do> SubTasks { get; set; } = new List<Do>();
}
you need to learn about the recursive CTE relationship
for the date configure there with Api
builder.Property(p => p.Created).HasDefaultValueSql("(newid())")
public class Task
{
[Key]
public int Id { get; set; }
[Required]
public string Title { get; set; }
[Required]
public string Description { get; set; }
public string Executors { get; set; }
public DoStatus Status { get; set; }
public DateTime Created { get; set; };
[Required]
public int Plan { get; set; }
public int Fact { get; set; }
public DateTime? Finished { get; set; }
public int DoId { get; set; } // id parent
public virtual List<Task> SubTasks { get; set; };
}
var id = 1 // id Do
var subTasks = db.Task.include(s => s.SubTasks).where(s => e.DoId = id).ToList()
I want to select from client model all client without duplicate client and order them by count of the purchases they already did
This is model of client :
public class Client
{
public int ID { get; set; }
public string FacebookName { get; set; }
public string RealName { get; set; }
public string Mobile { get; set; }
public int RegionID { get; set; }
public string Addressdetails { get; set; }
public string Email { get; set; }
[DataType(DataType.Date)]
public DateTime DateOfStart { get; set; }
public virtual Region Region { get; set; }
public virtual List<Order> order { get; set; }
}
this is Order model :
public class Order
{
public int ID { get; set; }
public int ClientID { get; set; }
public Nullable<int> ShippingID { get; set; }
public Nullable<int> SharepointID { get; set; }
public Nullable<int> CallStatuID { get; set; }
public Nullable<int> ShippingStatuID { get; set; }
public Nullable<int> ShippingStatuReasonsID { get; set; }
[DataType(DataType.Date)]
public DateTime Date { get; set; }
// public int OrderStatusID { get; set; }
public Nullable<decimal> ShippingCost { get; set; }
public string purchasetype { get; set; }
public string Notes { get; set; }
public Nullable<decimal> Discount { get; set; }
public decimal Total { get; set; }
[DefaultValue(false)]
public bool Prepared { get; set; }
[DefaultValue(false)]
public bool Done { get; set; }
[DefaultValue(false)]
public bool Shipe { get; set; }
[DefaultValue(false)]
public bool Collected { get; set; }
[DataType(DataType.Date)]
public Nullable<DateTime> DateOfCall { get; set; }
[DataType(DataType.Date)]
public Nullable<DateTime> StockCheckDate { get; set; }
[DataType(DataType.Date)]
public Nullable<DateTime> ShippingDate { get; set; }
public virtual List<OrderDetail> orderdetails { get; set; }
public virtual Client Client { get; set; }
public virtual Shipping shipping { get; set; }
public virtual Sharepoint sharepoint { get; set; }
public virtual CallStatu callStatu { get; set; }
public virtual ShippingStatu ShippingStatus { get; set; }
public virtual ShippingStatuReason ShippingStatuReasons { get; set; }
}
and finally this is OrderDetails model:
public class OrderDetail
{
public int ID { get; set; }
public int OrderID { get; set; }
public Nullable<int> ItemID { get; set; }
public Nullable<int> SizeID { get; set; }
public int ColorID { get; set; }
public decimal Price { get; set; }
public Nullable<int> StockStatuID { get; set; }
public Nullable<int> StockStatuReasonsID { get; set; }
public int Quantity { get; set; }
public decimal Total { get; set; }
public virtual Order order { get; set; }
public virtual Item item { get; set; }
public virtual Size size { get; set; }
public virtual Colors Colors { get; set; }
public virtual StockStatu stockStatus { get; set; }
public virtual StockStatuReason StockStatuReasons { get; set; }
}
I tried this way but it the select is repeat Clients If they make more than one purchase:
public JsonResult TopClientCount()
{
var index = (from dex in db.Clients
join O in db.Orders on dex.ID equals O.ClientID
select new
{
RealName = dex.RealName,
FacebookName = dex.FacebookName,
GovernorateName = dex.Region.governorate.GovernorateName,
RegionName = dex.Region.RegionName,
OrderCount = O.orderdetails.Count()
}).AsEnumerable().OrderByDescending(o => o.OrderCount)
.Distinct()
.ToList();
return Json(index, JsonRequestBehavior.AllowGet);
}
You can use let statement and you can use navigation properties i.e (order ,orderdetails) instead of joins
var index = (from dex in db.Clients
//This will give you all the order details for a client
let orderDetails = dex.order.SelectMany(p=> p.orderdetails)
select new
{
RealName = dex.RealName,
FacebookName = dex.FacebookName,
GovernorateName = dex.Region.governorate.GovernorateName,
RegionName = dex.Region.RegionName,
OrderCount = orderDetails.Count()
}).AsEnumerable().OrderByDescending(o => o.OrderCount)
.Distinct()
.ToList();
I have this complex model:
public class Food
{
[Key]
public int FoodID { get; set; }
[Required]
[DisplayName("Food Name")]
public string FoodNameEN { get; set; }
[Required]
[DisplayName("Food Name")]
public string FoodNameFR { get; set; }
[Required]
[DisplayName("Food Name")]
public string FoodNameNL { get; set; }
[Required]
[DisplayName("Food Description")]
public string FoodDescriptionEN { get; set; }
[Required]
[DisplayName("Food Description")]
public string FoodDescriptionFR { get; set; }
[Required]
[DisplayName("Food Description")]
public string FoodDescriptionNL { get; set; }
public int CategoryID { get; set; }
[Required]
public bool Availability { get; set; }
[Required]
[DisplayName("Is Menu of the Day")]
public bool DailyMenu { get; set; }
public virtual Category Category { get; set; }
public virtual ICollection<FoodAttributeValue> FoodAttributeValues { get; set; } = new HashSet<FoodAttributeValue>();
public virtual ICollection<OrderDetail> OrderDetails { get; set; } = new HashSet<OrderDetail>();
public class Category
{
[Key]
public int CategoryID { get; set; }
[Required(ErrorMessage = "Please enter a Category Name for English")]
[DisplayName("Category Name")]
public string CategoryEN { get; set; }
[Required(ErrorMessage = "Please enter a Category Name for French")]
[DisplayName("Category Name")]
public string CategoryFR { get; set; }
[Required(ErrorMessage = "Please enter a Category Name for Dutch")]
[DisplayName("Category Name")]
public string CategoryNL { get; set; }
[Required]
public bool Availability { get; set; }
public virtual ICollection<Food> Foods { get; set; } = new HashSet<Food>();
}
public class Attribute
{
[Key]
public int AttributeID { get; set; }
public string AttributeNameEN { get; set; }
public string AttributeNameFR { get; set; }
public string AttributeNameNL { get; set; }
public virtual ICollection<AttributeValue> AttributeValues { get; set; } = new HashSet<AttributeValue>();
}
public class AttributeValue
{
[Key]
public int AttributeValueID { get; set; }
public int AttributeID { get; set; }
public string AttributeValueEN { get; set; }
public string AttributeValueFR { get; set; }
public string AttributeValueNL { get; set; }
public virtual Attribute Attribute { get; set; }
public virtual ICollection<FoodAttributeValue> FoodAttributeValues { get; set; } = new HashSet<FoodAttributeValue>();
}
public class FoodAttributeValue
{
[Key]
[Column(Order = 0), ForeignKey("Food")]
public int FoodID { get; set; }
[Key]
[Column(Order = 1), ForeignKey("AttributeValue")]
public int AttributeValueID { get; set; }
public decimal Price { get; set; }
public string CreatorUserName { get; set; }
public DateTime DateCreated { get; set; }
public virtual Food Food { get; set; }
public virtual AttributeValue AttributeValue { get; set; }
}
Attributes contains an attribute type like size or volume
AttributeValue contains the values for an attribute, like Normal Size, or Large.
FoodAttributeValue is a many to many table with payload "Price". So basically, the same Food comes in different sizes with different Prices.
My DatabaseContext:
public class ModelContext: DbContext
{
public DbSet<Category> Categories { get; set; }
public DbSet<Food> Foods { get; set; }
public DbSet<Attribute> Attributes { get; set; }
public DbSet<AttributeValue> AttributesValues { get; set; }
public DbSet<FoodAttributeValue> FoodAttributeValues { get; set; }
}
How can i query the model using linq, with the intention to have on the same view, the list of Foods that contain also the Attributes of the Food, the AttributeValues of it and eventually the Price?
Thanks in advance!
In MVC it is a best practice to create a ViewModel (or DTO) designed for the view you want to display. Generally, try to avoid using your entity POCOs in the view.
So for example:
public class FoodIndexViewModel
{
// Add the various entity fields you want here.
public int FoodID { get; set; }
...
// Take all these annotations out of your entity model. They belong here.
[Required]
[DisplayName("Food Name")]
public string FoodNameEN { get; set; }
...
[Required(ErrorMessage = "Please enter a Category Name for English")]
[DisplayName("Category Name")]
public string CategoryEN { get; set; }
public decimal Price { get; set; }
... etc. etc.
}
Now you can compose a LINQ query to populate the view model. AutoMapper can greatly ease this process.
var listOfFoodsVM = context.Foods
.Where(food => food.Availability)
.Select(food => new FoodIndexViewModel
{
FoodId = food.FoodId,
FoodNameEN = food.FoodNameEN,
... // other fields from food
CategoryEN = food.Category.CategoryEN,
// Here you would either pick a single value from the list based on your criteria
Price = food.FoodAttributeValues.FirstOrDefault(fav => fav.AttributeValueID == 1).Price
// or you could include a collection of FoodAttributes in your viewmodel:
FoodAtributes = food.FoodAttributes
... etc.
}).ToList();
Now you pass this into your view.
return View(listOfFoodsVM );
I have two partial views named as _centerDetails.cshtml and _centerRights.cshtml .
I am passing data from centerdetails when I click on submit and want to show this when another partial view is switched, but without posting it to the server.
This is my model class which I have created to handling my data via
controller:
namespace ADWP_AdminWebPortal.Models
{
public class CountryList
{
[Required(ErrorMessage = "Select a Country.")]
public int CountryId { get; set; }
[Required]
public string Country { get; set; }
[Required(ErrorMessage = "Select a State.")]
public int StateId { get; set; }
[Required]
public string State { get; set; }
[Required(ErrorMessage = "Select a City.")]
public int CityId { get; set; }
[Required]
public string City { get; set; }
}
public class CustomerDetails: CountryList
{
public int ClientId { get; set; }
[Required (ErrorMessage="Eneter the First name")]
[DataType(DataType.Text)]
public string FirstName { get; set; }
[Required(ErrorMessage = "Eneter the Middle name")]
[DataType(DataType.Text)]
public string MiddleName { get; set;}
public string NatureOfOccupation { get; set; }
public string AgentId { get; set; }
[Required(ErrorMessage ="Select a Client Type.")]
public string ClientType { get; set; }
public int TariffId { get; set; }
public string TariffName { get; set; }
public int ServiceId { get; set; }
public string ServiceName { get; set; }
public string OrderId { get; set; }
public int PaymentMethodId { get; set; }
public string PaymentMethodName { get; set; }
}
}
Here you can see the mess I have created. My problem is how to handle multiple models when you are working with multiple models in same controller?
Here I did not created all the data in a single class because I wanted it to reuse as per my need.
How can I handling data in a model? This is the main problem that is
coming to me while I am creating the partial views in my project.
You may use CTE and ROW_NUMBER function together to delete duplicate rows from your table.
With CTE AS (
SELECT VERIFICATIONTYPE,
NAME,
COST,
RN = ROW_NUMBER() OVER (PARTITION BY VERIFICATIONTYPE, NAME, COST ORDER BY VERFICATIONTYPE)
FROM DETAILS)
DELETE FROM CTE WHERE RN > 1
END
After a bit of a struggle I got the result.
public class CountryList
{
[Required(ErrorMessage = "Select a Country.")]
public int CountryId { get; set; }
[Required]
public string Country { get; set; }
}
// Added Class
public class State
{
[Required(ErrorMessage = "Select a State.")]
public int StateId { get; set; }
[Required]
public string State { get; set; }
}
// Added Class
public class City
{
[Required(ErrorMessage = "Select a City.")]
public int CityId { get; set; }
[Required]
public string City { get; set; }
}
public class CustomerDetails
{
public int ClientId { get; set; }
[Required (ErrorMessage="Enter the first name")]
[DataType(DataType.Text)]
public string FirstName { get; set; }
[Required(ErrorMessage = "Enter the middle name")]
[DataType(DataType.Text)]
public string MiddleName { get; set; }
public int TariffId { get; set; }
public string TariffName { get; set; }
public int ServiceId { get; set; }
public string ServiceName { get; set; }
public string OrderId { get; set; }
public int PaymentMethodId { get; set; }
public string PaymentMethodName { get; set; }
public List<CountryList> { get; set; } //added list
public List<State> { get; set; } //added list
public List<City> { get; set; } //added list
}
Yeah, it was so easy.
I have the following tables:
**Table Person**
public long Id { get; set; }
public int Number { get; set; }
public string Name { get; set; }
public string NameDesportivo { get; set; }
public string Title { get; set; }
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime Birthdate { get; set; }
public Nullable<int> CC { get; set; }
public Nullable<int> NIF { get; set; }
public Nullable<bool> Active { get; set; }
public string Natural { get; set; }
public string Nacionality { get; set; }
public string fatherName { get; set; }
public string motherName { get; set; }
public string street { get; set; }
public string numberDoor { get; set; }
public string local { get; set; }
public string parish { get; set; }
public int Id_Contacto { get; set; }
public virtual ICollection<Contact> Contact { get; set; }
public HabLiterarias HabLiterarias { get; set; }
**Table ContactPerson**
public int ContactID
public int PersonId
**Table ContactType**
public long ID { get; set; }
public string Name { get; set; }
public Nullable<bool> Active { get; set; }
public string UserIDModification { get; set; }
public Nullable<System.DateTime> DataModification { get; set; }
public virtual ICollection<Contact> Contact { get; set; }
**Table Contact**
public long ID { get; set; }
public Nullable<long> ContactTypeID { get; set; }
public string ContactValue { get; set; }
public virtual ContactType ContactType { get; set; }
public virtual ICollection<Person> Person { get; set; }
What I'm trying to do is when I create an Person insert more than one contact of that person at the some time: For example Insert type contact mail and it´s value and contact type phone and it's value into the table contact.
Those any one have any ideias. Thank you