Enity Framework Foreign Key - asp.net

I have three enities
public class Customer
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public int Customerid { get; set; }
public string Name { get; set; }
public string email { get; set; }
public string Phoneno { get; set; }
}
and second Enitity
public class Merchant
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Merchantid { get; set; }
[Required]
[RegularExpression("^[\\p{L} .-]+$", ErrorMessage = "Use letters only please")]
public string MerchantName { get; set; }
[Required]
[RegularExpression("^[\\p{L} .-]+$", ErrorMessage = "Use letters only please")]
public string BusinessName { get; set; }
[Required]
public string OfficePhno { get; set; }
}
public class Transaction
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int TransactionId { get; set; }
public int Merchantid {get; set;}
public int Customerid {get; set;}
public int Amount { get; set; }
public Customer customer {get; set;}
public Merchant merchant {get; set;}
}
in above Transaction table has two IDs Merchant ID and Customer ID i want this to foreign keys of customer and merchant table,
please explain me how to add the foreign key Constraints I went through many examples but was not able to get the answer for this
and another doubt is if i add Customer type inside Transaction table will I able to fetch details of customer in transaction table in Entity
Framework
I am trying to add Constraint by follwing code
[ForeignKey("Customerid")]
pubic virtual Customer customer {get; set;}
I am getting an exception as below
Additional information: The ForeignKeyAttribute on property 'Customer'
on type 'Dutch.Models.Transaction' is not valid. The foreign key name
'Customerid' was not found on the dependent type
'Dutch.Models.Transaction'. The Name value should be a comma separated
list of foreign key property names.

I finally did by Foreignkey constraint
My Model looks like this now
public class Customer
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public int Customerid { get; set; }
public string Name { get; set; }
public string email { get; set; }
public string Phoneno { get; set; }
public ICollection<Transaction> Transactions { get; set; }
}
public class Merchant
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Merchantid { get; set; }
[Required]
[RegularExpression("^[\\p{L} .-]+$", ErrorMessage = "Use letters only please")]
public string MerchantName { get; set; }
[Required]
[RegularExpression("^[\\p{L} .-]+$", ErrorMessage = "Use letters only please")]
public string BusinessName { get; set; }
[Required]
public string OfficePhno { get; set; }
public ICollection<Transaction> Transactions { get; set; }
}
So Customer and Merchants will have a collection of transactions
and in transaction table
public class Transaction
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int TransactionId { get; set; }
public int Merchantid {get; set;}
public int Customerid {get; set;}
public int Amount { get; set; }
[ForeignKey("Customerid")]
public Customer customer {get; set;}
[ForeignKey("Merchantid")]
public Merchant merchant {get; set;}
}

Related

When creating a one-to-one relationship in an entity it throws an error The navigation property 'StudentModel' was not found on the dependent type

I want to create one to one relation between tables. My table is
public class StudentModel
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime DateOfBirth { get; set; }
[Required, Display(Name="Department Name")]
public int DeptId { get; set; }
//navigration proprty
[ForeignKey("DeptId")]
public virtual DepartmentModels Department { get; set; }
public virtual StudentRegistrationModels StudentRegistration { get; set; }
}
and my other table is
public class StudentRegistrationModels
{
[Key]
public int StudentId { get; set; }
[Required]
public int CourseId { get; set; }
[Required]
public DateTime EnrollDate { get; set; }
public bool IsPaymentComplete { get; set; }
//navigration proprty
[ForeignKey("StudentId")]
public virtual StudentModel Student { get; set; }
[ForeignKey("CourseId")]
public virtual CourseModels Course { get; set; }
//oneToOneStudentRegistration
}
But when I make migration it throws an error:
Unable to determine the principal end of an association between the types 'StudentManagementSystem.Models.StudentModel' and 'StudentManagementSystem.Models.StudentRegistrationModels'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.
Why is this occurring?
I believe the issue is that you have a single StudentRegistrationModel instance in your StudentModel, where the StudentRegistrationModel looks to be more of a Many-to-Many structure. Can a single student only be registered to a single course? If that were the case it would make more sense for StudentModel to just have a CourseModel reference. Since a Student probably has multiple courses, it would probably make more sense for StudentModel to have:
public virtual ICollection<StudentRegistrationModels> StudentRegistration { get; set; } = new List<StudentRegistrationModels>();
Then ensuring that your model configuration maps out the relationship. This can be done with an attribute, as part of the DbContext OnModelCreating, or using an EntityTypeConfiguration. With Attributes:
[InverseProperty("Student")] // Tells EF this collection corresponds to the Student on the StudentRegistrationModel.
public virtual ICollection<StudentRegistrationModels> StudentRegistration { get; set; } = new List<StudentRegistrationModels>();
Maybe try to add [Key] annotation to Id field in StudentModel.
using System.ComponentModel.DataAnnotations;
public class StudentModel
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime DateOfBirth { get; set; }
[Required, Display(Name="Department Name")]
public int DeptId { get; set; }
//navigration proprty
[ForeignKey("DeptId")]
public virtual DepartmentModels Department { get; set; }
public virtual StudentRegistrationModels StudentRegistration { get; set; }
}
or if it won't work try map relationship in OnModelCreating in your data context.

Need to create an API on the basis of ForeignKey in dotnet core

Here is my Schema and with two Foreign Key in an intermediate table. I am beginner in Core dotnet so unable to crate API to show the department in the school.
public class DepartmentSchool
{
public int Id { get; set; }
public int DepartmentID { get; set; }
[ForeignKey("DepartmentID")]
public virtual Department Department{ get; set; }
public int SchoolsId { get; set; }
[ForeignKey("SchoolsId")]
public virtual Schools Schools { get; set; }
Here I want to get all department related to school id, how can i get all the department though the School id in dotnetcore API.
Here is the school class entity schema.
public partial class Schools
{
public int ID { get; set; }
public string UicCode { get; set; }
public int SchoolSystemsId { get; set; }
public string BannerUrl { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string ImageUrl { get; set; }
public int UserID { get; set; }
public int? Status { get; set; }
public DateTime? CreatedAt { get; set; }
public int? CreatedBy { get; set; }
public DateTime UpdatedAt { get; set; }
public int? ModifiedBy { get; set; }
[ForeignKey("SchoolSystemsId")]
public PrivateSchoolSystem PrivateSchoolSystems { get; set; }
And more here is the department schema.
public partial class Department
{
public int Id { get; set; }
public string Title { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
public int CreatedBy { get; set; }
public int UpdatedBy { get; set; }
public int SchoolSystemsID { get; set; }
[ForeignKey("SchoolSystemsID")]
public virtual PrivateSchoolSystem PrivateSchoolSystems { get; set; }
And I am trying to get a department list in the query in the following controller.
[Route("api/[controller]")]
[ApiController]
public class DepartmentSchoolController : ControllerBase
{
private readonly learning_gpsContext _learning_GpsContext;
public DepartmentSchoolController(learning_gpsContext learning_GpsContext)
{
_learning_GpsContext = learning_GpsContext;
}
[HttpGet("school/{schoolId}/departments")]
public IActionResult GetDepartmentsFromSchool(int schoolId)
{
var school = _learning_GpsContext.Schools.Where(e=>e.Id == schoolId).FirstOrDefault();
if (school == null)
return NotFound();
var departments = _learning_GpsContext.DepartmentSchool
.Where(e=>e.SchoolsId == schoolId).Select(e=>e.Department);
return Ok(departments);
}
For further learning check this tutorial. You should also understand what REST is and for basic questions always take a look at the official documenation.

Online Shop - Create an order with multiple products MVC .net

So I am building an online shop using Code-First MVC
So I created this model classes for now (don't take the types of the attributes too serious for now):
Products (Produto):
public Produto()
{
ListaProdutoEncomenda = new HashSet<Produto_Encomenda>();
}
public int ProdutoID { get; set; }
[Required]
[StringLength(50)]
public string Nome { get; set; }
[Required]
public double Preco { get; set; }
[Required]
public double Peso { get; set; }
[Required]
[StringLength(255)]
public string Descricao { get; set; }
[Required]
public double IVA { get; set; }
public string Imagem { get; set; }
public DateTime UltimaAtualizacao { get; set; }
public int Stock { get; set; }
public int CategoriaID {get;set;}
public virtual ICollection<Produto_Encomenda> ListaProdutoEncomenda { get; set; }
}
Encomenda (Order):
public class Encomenda
{
public Encomenda()
{
ListaProdutoEncomenda = new HashSet<Produto_Encomenda>();
}
[Key]
public int IDEncomenda { get; set; }
[Required]
public DateTime DataSubmissao { get; set; }
[Required]
public DateTime DataEnvio { get; set; }
[Required]
public int EstadoEnvioID { get; set; }
[StringLength(50)]
public string NomeDestino { get; set; }
[Required]
public int TipoExpedicaoID { get; set; }
[Required]
public int RegiaoDestinoID { get; set; }
[StringLength(50)]
public string MoradaDestino { get; set; }
[StringLength(50)]
public string CodPostalDestino { get; set; }
[Required]
[StringLength(50)]
public string MoradaFaturacao { get; set; }
[Required]
[StringLength(50)]
public string CodPostalFaturacao { get; set; }
public virtual ICollection<Produto_Encomenda> ListaProdutoEncomenda { get; set; }
}
And the connection table between the produtos (Products) and Encomenda (Order)
public class Produto_Encomenda
{
[Key]
public int IDProduto_Encomenda { get; set; }
[Required]
public string NomeProduto { get; set; }
[Required]
public int Quantidade { get; set; }
[Required]
public float preco { get; set; }
[Required]
public float IVA { get; set; }
public virtual Encomenda Encomenda { get; set; }
public virtual Produto Produto { get; set; }
[ForeignKey("Encomenda")]
public int IDEncomendaFK { get; set; }
[ForeignKey("Produto")]
public int IDProdutoFK { get; set; }
}
So my question is..
Let's pretend that a costumer buys 2 or 3 products or more.
How can I store all this products in a single line of an order?
Cheers and thanks a lot in advance for the time spent reading.
I'm not sure what you mean by "a single line of an order". Each product is a separate line item, and your entities already model this through the many-to-many relationship.
However, in general this setup is a very bad idea. Your order should not be directly related to products. Instead, your order should simply have an order item, and you'll create those order items based on the products that were sold. The reason for this is that products are very likely to change. If a product is removed because it's no longer available, for example, that doesn't negate the fact that it was previously sold in an order. However, in order for referential integrity to be maintained, any orders sold with that product would have to also have their relationship with that product removed. By having an entirely separate entity, i.e. order item, products can come and go, while the already created orders remain unaffected.
I guess you are looking to make a viewmodel
Create a class that contains Products and Encomenda class as property -
Model -
public class MyViewModel
{
public Produto Pinst{get;set;}
public Encomenda Einst{get;set;}
}
Controller or method-
public void SomeMethod()
{
List<MyViewModel> lst = new List<MyViewModel>();
//Now suppose
foreach(var items in listThatGetCreatedWithBuyerproductInfo)
{
MyViewModel obj = new MyViewModel ();
obj.Pinst = new Produto();
obj.Einst = new Encomenda();
//Here goes your properties from item in respected class instances
obj.Pinst.Nome = items.Nome;
obj.Einst.DataSubmissao = items.DataSubmissao;
//when you are done loading add obj to list
lst.Add(obj);
}
}
Hope it Helps if it does not tell me !!

How do I also get the sum of a child table in web api?

This is my Order model:
public class Order
{
[Key]
public int OrderID { get; set; }
[Column(TypeName = "Date")]
public DateTime? OrderDate { get; set; }
public string OrderStatus { get; set; }
public string CreatedBy { get; set; }
public DateTime? CreatedDate { get; set; }
public DateTime? ModifiedDate { get; set; }
public int? Active { get; set; }
public int? CreditorID { get; set; }
public virtual Creditor Creditor { get; set; }
public virtual ICollection<OrderItem> OrderItems { get; set; }
}
This is my OrderItem model:
public class OrderItem
{
[Key]
public int OrderItemID { get; set; }
public string ItemDescription { get; set; }
public int ItemQty { get; set; }
public decimal ItemUnitPrice { get; set; }
public int ItemTaxGroup { get; set; }
public decimal ItemTotalTax { get; set; }
public decimal ItemTotalPrice { get; set; }
public int OrderID { get; set; }
public virtual Order Order { get; set; }
}
This is my current controller query:
return db.Orders.Where(order => order.Active == 1);
This returns the following json:
{"OrderID":3,"OrderDate":"2014-11-26T00:00:00","OrderStatus":"Draft"},
{"OrderID":4,"OrderDate":"2014-11-26T00:00:00","OrderStatus":"Draft"},
{"OrderID":5,"OrderDate":"2014-11-26T00:00:00","OrderStatus":"Draft"}
Using SQL this is what I need it to return (the sum of the related OrderItems):
SELECT PT.*, (SELECT SUM([ItemTotalPrice]) FROM [OrderItems] AS CT WHERE CT.OrderID = PT.OrderID) AS OrderTotal
FROM [Orders] AS PT
WHERE PT.Active = 1
This is what I need it to return in json:
{"OrderID":3,"OrderDate":"2014-11-26T00:00:00","OrderStatus":"Draft","OrderTotal":189.95},
{"OrderID":4,"OrderDate":"2014-11-26T00:00:00","OrderStatus":"Draft","OrderTotal":88.0},
{"OrderID":5,"OrderDate":"2014-11-26T00:00:00","OrderStatus":"Draft","OrderTotal":0.0}
You need a new select for your items and i'm not sure how your setup is, but you will probably want to create a new model/viewmodel to hold your data in. Something like this
public class OrderViewModel {
public int OrderId {get; set;}
public DateTime OrderDate {get; set;}
public string OrderStatus {get; set;}
public decimal OrderTotal {get; set;}
}
Then your select will look something along these lines,
var orders = (from o in Orders
where o.Active == 1
select new OrderViewModel
{ OrderId = o.OrderId,
OrderDate = o.OrderDate,
OrderStatus = o.OrderStatus,
OrderTotal = o.OrderItems.Sum(oi => oi.ItemTotalPrice)
});

Code first one to one foreign key

I have two model class, where I want to make one-to-one relation. When I make migration, I get an error:
The ALTER TABLE statement conflicted with the FOREIGN KEY constraint
"FK_dbo.Uzytkownik_dbo.UserProfile_UserId". The conflict occurred in
database "db_wydarzenia", table "dbo.UserProfile", column 'UserId'.
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
}
[Table("Uzytkownik")]
public class Uzytkownik
{
[Key]
public int UzytkownikID { get; set; }
public int UserId { get; set; }
public string Imie { get; set; }
public string Nazwisko { get; set; }
public string Telefon { get; set; }
public string Email { get; set; }
[ForeignKey("UserId")]
public UserProfile UserProfile { get; set; }
}
EDIT:
Problem solved :)
I remove all data from uzytkownik table and it's go.
If you want one-to-one - you cannot have both the primary-key and the foreign-key specified. One-to-one is modeled via primary-keys (pk == pk), otherwise it becomes 'multiplicity' (and just typical one-to-many).
To get what you want just remove your other PK - and user UserId as both primary and fk...
[Table("Uzytkownik")]
public class Uzytkownik
{
// [Key] public int UzytkownikID { get; set; }
[Key]
public int UserId { get; set; }
[ForeignKey("UserId")]
public UserProfile UserProfile { get; set; }
}

Resources