How can i add a foreign key to a Model (code first)
i have a model Product which has an ID (primary key) which i want to add to my model order like.
public class Order
{
public int ID {get; set;}
[Required]
public int Total {get; set;}
[Required]
public int ProductId{get; set;}
}
but how can i make the ProductId refer to the id of my Product model like a foreign key?
On Stackoverflow there are alot simmilar questions but all with different answers, but they arent working for me. I really hope someone has a solution or can points me in the right direction with an explanation.
You need to add a navigation property:
public virtual Product Product { get; set; }
So the Order class will look like this:
public class Order
{
public int ID {get; set;}
[Required]
public int Total {get; set;}
[Required]
public int ProductId{get; set;}
[Required]
public virtual Product Product { get; set; }
}
Also, strictly speaking the ProductId property isn't needed once you have the virtual Product property.
You could do something like this:
public class Order
{
public int ID {get; set;}
[Required]
public int Total {get; set;}
[Required]
public int ProductId{get; set;}
[ForeignKey("ProductId")]
public virtual Product Product {get; set;}
}
Related
I am creating a web app using C# MVC. I created a model named Trip.cs with properties as below:
public int ID {get; set;}
public string Destination {get; set;}
public DateTime DepartureDate {get; set;}
public string MeetPlace {get; set;}
public int NumberOfSeats {get; set;}
public virtual ApplicationUser User { get; set; }
public string UserId { get; set; }
I created another model called ReservedTrip.cs identical with Trip.cs with the same properties.
What I do is when the logged user clicks on the Actionlink named "Reserve Trip", I save this "Trip" to the ReservedTrip.cs and I decrease the number of property NumberOfSeats with 1. So in other words I copy this "Trip" data from Trip.cs to ReservedTrip.cs. The problem is when I display in a view the data from model Trip.cs the number of NumberOfSeats changes, but in the model ReservedTrip.cs the property NumberOfSeats doesn't change. So I want the changes of property NumberOfSeats of model Trip.cs to change in the property NumberOfSeats to be changed with the same value.
Can anyone help me?
From a design standpoint, it is better to not have a copy of any table. A good design for this situation can be something like this.
public class Trip
{
public int ID {get; set;}
public string Destination {get; set;}
public DateTime DepartureDate {get; set;}
public string MeetPlace {get; set;}
public int NumberOfSeats {get; set;}
public int CreatedByUserID {get; set;}
public virtual ApplicationUser CreatedByUser {get; set;}
public virtual ICollection<TripReservation> Reservations {get;set;}
}
public class TripReservation
{
public int ID {get; set;}
public int TripID {get; set;}
public int UserID {get; set;}
public virtual Trip Trip {get; set;}
public virtual ApplicationUser User {get; set;}
}
then in your controller you can construct a view model with the number of seats available being
numberOfSeatsAvailable = trip.NumberOfSeats - trip.Reservations.Count();
If a reservation can reserve more than 1 seat, you can sum that from all reservations for that trip.
Example: ViewModel
public class TripReservationsViewModel
{
public Trip Trip { get; set; }
public int NumberOfSeatsAvailable { get; set; }
}
Example: Controller
public ActionResult TripDetails(int id)
{
var trip = db.Trips.FirstOrDefault(trip => trip.ID == id);
if (trip == null)
{
// Trip does not exist,
// Redirect the user to the trips home page
//
return RedirectToAction("Index");
}
var viewModel = new TripReservationsViewModel();
viewModel.Trip = trip;
viewModel.NumberOfSeatsAvailable = trip.NumberOfSeats - trip.Reservations.Count();
return View(viewModel);
}
Example: View
#model TripReservationsViewModel
<h1>Trip Details</h1>
<p>Seats available: #Model.NumberOfSeatsAvailable</p>
etc...
I am trying to work out how to add a reference an object from within EF.
I little hard to explain so I thought I would share a dotnetfiddle example
https://dotnetfiddle.net/4n5Flk
public class ReportConfig
{
[Key]
public int ReportConfigKey {get; set;}
public int ConfigTypeKey {get; set;}
public int ConfigValue {get; set;}
[ForeignKey("ConfigTypeKey")]
public virtual <ConfigType> ConfigType {get; set;}
}
public class ConfigType
{
[Key]
public int ConfigTypeKey {get; set;}
//This can be
//Address
//Car etc etc.
public string ConfigName {get; set;}
}
public class Car
{
[Key]
public int CarId {get; set;}
//other items
}
public class Address
{
[Key]
public AddressId {get; set;}
}
In a nutshell I am trying to create a navigation property to either a car or an address based on the ConfigValue and the ConfigTypeKey
I was thinking to create 2 navigation properties "Car" and "Address" and for both add 2 foreign key's 1 to the object and 1 as a hardcoded reference to ConfigName as Car or Address
is this possible atall
Sorry for the poor explanation.
I have the following models:
public class Order
{
public int Id {get; set;}
public int CustomerId {get; set;}
public virtual Category Category {get; set;}
//Many more properties...
}
public class OrderLine
{
public int Id {get; set;}
public int OrderId {get; set;}
public virtual Order Order {get; set;}
public virtual Product Product {get; set;}
//Other properties...
}
I need to get the orders of a particular customer. In order not to retrieve too many information, I created a class:
public class CustomerOrder
{
public int CustomerId {get; set;}
public int OrderId {get; set;}
public string ProductName {get; set;}
public virtual ICollection<OrderLine> {get; set;}
}
I have mapping configuration for the Order and OrderLine classes but none for CustomerOrder as I was thinking that I can project data into this class.
I can:
Use EF to retrieve the data by specifying includes. After the data is retrieved I can project it into the CustomerOrder class. However, will this force EF to retrieve all columns for the main and included tables?
Use a custom SQL query to retrieve the required details from the Order table (maybe directly from a view). The use Linq to join this resultset with OrderLine to have the complete projection. However, will I need to have mapping configuration for the view?
To avoid too many columns and join in the SQL select statement, what is the best way to project the data into CustomerOrder?
You can do it as shown below.You have to do some changes on your models as well.I have done that.Please see that too.
public class Order
{
public int Id {get; set;}
public int CustomerId {get; set;}
public virtual Category Category {get; set;}
public virtual ICollection <OrderLine> OrderLines {get; set;}
//Many more properties...
}
public class OrderLine
{
public int Id {get; set;}
public int OrderId {get; set;}
public virtual Order Order {get; set;}
public virtual Product Product {get; set;}
//Other properties...
}
public class CustomerOrder
{
public int CustomerId {get; set;}
public int OrderId {get; set;}
public string ProductName {get; set;}
public virtual ICollection<OrderLine> OrderLines {get; set;}
}
Final Query :
var orderList = (from order in _context.Orders
from orderLine in order.OrderLines)
select new CustomerOrder
{
CustomerId = order.CustomerId,
OrderId = orderLine.OrderId,
ProductName= orderLine.Product.ProductName,
OrderLines = order.OrderLines
}).AsNoTracking().ToList();
A 1 : No.Only the projected columns will be fetched from the db.
Best Approach : Always use the custom projection (like CustomerOrder).That is the best when we consider the Performance of the EF query.You can use that to send data to the View too (it's like a DTO (Data Transfer Object)).
Provided I have two code-first entities:
User:
public class User
{
public User() {}
[Key]
public int Id {get; set;}
public string Name {get; set;}
public string City {get; set;}
}
City:
public class City
{
public City() {}
[Key]
public string Name {get; set;}
}
How do I make a Foreign key relationship so that the User table will have a City_Name FK, containing a string that has to correspond to one of the Names from the City table? I don't need the reference in the other direction, I just want to make sure that the City_Name in dbo.Users will be from the Name column in the dbo.Cities.
If I just make a migration with a model like that, it will create the City_Name column in dbo.Users and Inserting works fine, but if I want to return a User obj, the City is always null, even if I manually load the City with dbContext.Entry(user).Reference(u => u.City).Load().
Any ideas or insights to what I might be doing wrong, and how is this kind of a relationship achieved in EF ?
Like this:
public class User
{
[Key]
public int Id {get; set;}
public string Name {get; set;}
[ForeignKey("CityMappedToUser")]
public string City_Name {get; set;}
public virtual City CityMappedToUser{get; set;}
}
It's explained pretty good on msdn tbh: https://msdn.microsoft.com/en-us/data/jj713564.aspx
It seems like you need something like this:
public class User
{
public User() {}
[Key]
public int Id {get; set;}
public string Name {get; set;}
public string City_Name {get; set;}
[ForeignKey("City_Name")]
public virtual City City { get; set; }
}
public class City
{
public City() {}
[Key]
public string Name {get; set;}
}
I have a DB that looks like this:
Houses
- HouseId
Rooms
- RoomId
HouseRooms
- HouseRoomId
- HouseId
- RoomId
class House
{
[Key]
public virtual int HouseId{ get; set; }
public DbSet<HouseRoom> Rooms{ get; set; }
}
class HouseRoom
{
[Key]
public virtual int HouseRoomId{ get; set; }
public virtual int HouseId{ get; set; }
public virtual int RoomId{ get; set; }
[ForeignKey("RoomId")]
Public Role RoomInfo {get; set;}
}
class Room
{
[Key]
public virtual int RoomId {get; set;}
public string RoomName {get; set;}
}
I just need the House entity/mode to load all the rooms records. Noticed that the JOIN table has a PK name HouseRoomId but this is not the key that need to match the key in House. House.HouseId need to match HouseRoom.HouseId.
How can I get this to work?
Ok first this is a many-to-many, not one-to-many. Second, you need to set the relationship on ModelCreation to let the DbContext know about this relationship. Also, you need to make your List<Room> virtual to enable it to load when you need it.
Please look at this example.
Code First Entity Framework Many-to-Many relationships
Also, for the record, you do not need to specify [key], it is already there for you by default