How can I save data to junction table from controller?
public ActionResult Create(KreatorZamowienNabywca model)
{
db.KreatoryZamowien.Add(model.KreatorZamowien);
db.Nabywcy.Add(model.Nabywca);
db.SaveChanges();
}
My database schema:
KreatorZamowien(Id, NumerZamowienia) -------------------------------|
|
NabywcaKreatorzamowien (KreatorZamowien_Id, Nabywca_Nabywca_Id)------|
|
Nabywca(Nabywca_Id, Nazwa) ------------------------------------------|
KreatorZamowien.cs
public class KreatorZamowien
{
public int Id { get; set; }
public int NumerZamowienia { get; set; }
public virtual ICollection<Nabywca> Nabywcy { get; set; }
}
Nabywca.cs
public class Nabywca
{
public int NabywcaId { get; set; }
public string Nazwa { get; set; }
public virtual ICollection<KreatorZamowien> KreatoryZamowien { get; set; }
}
Model containing 2 models to display them in View:
KreatoryZamowienNabywca.cs
public class KreatorZamowienNabywca
{
public KreatorZamowien KreatorZamowien { get; set; }
public Nabywca Nabywca { get; set; }
}
Just cross reference both objects.
public class KreatorZamowien
{
public int Id { get; set; }
public int NumerZamowienia { get; set; }
public virtual ICollection<Nabywca> Nabywcy { get; set; } = new Hashset<Nabywca>();
}
public class Nabywca
{
public int NabywcaId { get; set; }
public string Nazwa { get; set; }
public virtual ICollection<KreatorZamowien> KreatoryZamowien { get; set; } = new Hashset<KreatorZamowien>();
}
public ActionResult Create(KreatorZamowienNabywca model)
{
model.KreatorZamowien.Nabywcy.Add(model.Nabywca);
model.Nabywca.KreatoryZamowien.Add(model.KreatorZamowien);
db.KreatoryZamowien.Add(model.KreatorZamowien);
db.Nabywcy.Add(model.Nabywca);
db.SaveChanges();
}
Related
I have these 3 models:
public class Example1
{
public int ID_Ex1 { get; set; }
public int Attr1 { get; set; }
public int Attr2 { get; set; }
public int Attr3 { get; set; }
}
public class Example2
{
public int ID_Ex2 { get; set; }
public int Attr3 { get; set; }
public int Attr4 { get; set; }
public int Attr5 { get; set; }
public virtual Example1 example1 { get; set; }
}
public class Example3
{
public int ID_Ex3 { get; set; }
public int Attr6 { get; set; }
public int Attr7 { get; set; }
public int Attr8 { get; set; }
public virtual Example1 example1 { get; set; }
}
and the ViewModel, I took all attributes from the model above (just in case):
public class ExampleViewModel
{
// Example 1
public int ID_Ex1 { get; set; }
public int Attr1 { get; set; }
public int Attr2 { get; set; }
public int Attr3 { get; set; }
// Example 2
public int ID_Ex2 { get; set; }
public int Attr3 { get; set; }
public int Attr4 { get; set; }
public int Attr5 { get; set; }
// Example 3
public int ID_Ex3 { get; set; }
public int Attr6 { get; set; }
public int Attr7 { get; set; }
public int Attr8 { get; set; }
}
In the controller, how do I return ExampleViewModel.ToList() for showing the data in the Index view, or is there another way?
Thank you very much.
In Generally, When using ViewModel, We just put the Model we need in ViewModel instead of their properties. ViewModel is just a model passed data between controller and View, You can't just use ExampleViewModel.ToList() directly.
From your question, I think you just want to pass List of ExampleViewModel from controller to view, And i also noticed that you have one-to-one relationship in your models, So i write a simple demo here, You can refer to it.
For tesing convenience, I just change the properties to Name
public class Example1
{
public int ID_Ex1 { get; set; }
public string Name { get; set; }
}
public class Example2
{
public int ID_Ex2 { get; set; }
public string Name { get; set; }
public virtual Example1 example1 { get; set; }
}
//.......
ExampleViewModel
public class ExampleViewModel
{
public Example1 Example1s { get; set; }
public List<Example2> Example2s { get; set; }
public List<Example3> Example3s { get; set; }
}
Controller
public IActionResult Index()
{
List<ExampleViewModel> models = new List<ExampleViewModel>();
//select all Example1 from db frist
var example1s = _dbContext.Example1.ToList();
foreach (var example in example1s)
{
ExampleViewModel exampleViewModel = new ExampleViewModel();
//select Example2 and Example3 corresponding to Example1
var example2 = _dbContext.Example2.Where(x => x.example1.ID_Ex1 == example.ID_Ex1).ToList();
var example3 = _dbContext.Example3.Where(x => x.example1.ID_Ex1 == example.ID_Ex1).ToList();
exampleViewModel.Example1s = example;
exampleViewModel.Example2s = example2;
exampleViewModel.Example3s = example3;
models.Add(exampleViewModel);
}
return View(models);
}
Then in the view, You can use #foreach() to get each item of list<ExampleViewModel>
I hope it is what you want.
public class LootItem
{
public int Id { get; set; }
public string Name { get; set; }
public string Ilvl { get; set; }
public ItemSlot slot { get; set; }
public virtual ICollection<LootPlayer> Player { get; set; }
public virtual ICollection<LootPlayer> PlayerBis { get; set; }
public LootItem()
{
Player = new List<LootPlayer>();
PlayerBis = new List<LootPlayer>();
}
}
public class LootPlayer
{
public int Id { get; set; }
public string Name { get; set; }
public LootClass PlayerClass { get; set; }
public LootRole PlayerRole { get; set; }
public virtual ICollection<LootItem> CurrentGear { get; set; }
public virtual ICollection<LootItem> BisGear { get; set; }
public LootPlayer()
{
CurrentGear = new List<LootItem>();
BisGear = new List<LootItem>();
}
}
I'm trying to create 2 x many to many relations between these 2 tables.
Player <-> CurrentGear
PlayerBis <-> BisGear
Is this posible, because currently when I run the Update-Database I don't get any relationship tables. Only LootItem and LootPlayer
You Can't create many-to-many relationship. you should create two one-to-many relationship like this. create an class like this
public class LootPlayerLootItem
{
public int Id { get; set; }
public int PlayerId { get; set; }
public int PlayerBisId { get; set; }
public int CurrentGearId { get; set; }
public int BisGearId { get; set; }
[ForeignKey("CurrentGearId")]
public LootPlayer CurrentGear { get; set; }
[ForeignKey("BisGearId")]
public LootPlayer BisGear { get; set; }
[ForeignKey("PlayerId")]
public LootItem Player { get; set; }
[ForeignKey("PlayerBisId")]
public LootItem PlayerBis { get; set; }
}
then change the LootItem and LootPlayer to this
public class LootItem
{
public int Id { get; set; }
public string Name { get; set; }
public string Ilvl { get; set; }
public ItemSlot slot { get; set; }
[InverseProperty("Player")]
public virtual ICollection<LootPlayerLootItem> Player { get; set; }
[InverseProperty("PlayerBis")]
public virtual ICollection<LootPlayerLootItem> PlayerBis { get; set; }
public LootItem()
{
Player = new List<LootPlayerLootItem>();
PlayerBis = new List<LootPlayerLootItem>();
}
}
public class LootPlayer
{
public int Id { get; set; }
public string Name { get; set; }
public LootClass PlayerClass { get; set; }
public LootRole PlayerRole { get; set; }
[InverseProperty("CurrentGear")]
public virtual ICollection<LootPlayerLootItem> CurrentGear { get; set; }
[InverseProperty("BisGear")]
public virtual ICollection<LootPlayerLootItem> BisGear { get; set; }
public LootPlayer()
{
CurrentGear = new List<LootPlayerLootItem>();
BisGear = new List<LootPlayerLootItem>();
}
}
public IEnumerable<Parties> GetAll()
{
return database.Parties;
}
Works very well and the output is:
But when I Include another table by foreignkey like this:
public IEnumerable<Parties> GetAll()
{
return database.Parties.Include(i=>i.User);
}
It does not work, it returns first value of the table and nothing else,the output is :
Users.cs :
public partial class Users
{
public Users()
{
Parties = new HashSet<Parties>();
PartyParticipants = new HashSet<PartyParticipants>();
}
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string Username { get; set; }
public string Email { get; set; }
public string Avatar { get; set; }
public string Biography { get; set; }
public string Password { get; set; }
public virtual ICollection<Parties> Parties { get; set; }
public virtual ICollection<PartyParticipants> PartyParticipants { get; set; }
}
Parties.cs :
public partial class Parties
{
public Parties()
{
Image = new HashSet<Image>();
PartyParticipants = new HashSet<PartyParticipants>();
}
public int Id { get; set; }
public string Name { get; set; }
public DateTime PartyDate { get; set; }
public DateTime CreatedDate { get; set; }
public int ParticipantCount { get; set; }
public int MaxParticipant { get; set; }
public string PartySplash { get; set; }
public string ShortDescription { get; set; }
public string Description { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public bool EntranceFree { get; set; }
public int? FreeParticipant { get; set; }
public int? FreeParticipantMax { get; set; }
public int UserId { get; set; }
public virtual Users User { get; set; }
public virtual ICollection<Image> Image { get; set; }
public virtual ICollection<PartyParticipants> PartyParticipants { get; set; }
}
As you can see on the 2nd picture it interrupts at first row of the table.
I have added this answer based on Vidmantas's comment. ReferenceLoopHandling should be ignored like this in startup.cs:
services.AddMvc()
.AddJsonOptions(options =>
{
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
});
What could be wrong here? I have seen others include multilevel class to Lambda expression using Select, but I'm getting this error. Can anyone help please?
public partial class Employee
{
public Employee()
{
EmployeeRole = new HashSet<EmployeeRole>();
}
public int Id { get; set; }
public string Name { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public virtual ICollection<EmployeeRole> EmployeeRole { get; set; }
}
public partial class EmployeeRole
{
public int EmployeeId { get; set; }
public int RoleId { get; set; }
public virtual Employee Employee { get; set; }
public virtual Role Role { get; set; }
}
public partial class Role
{
public Role()
{
EmployeeRole = new HashSet<EmployeeRole>();
}
public int Id { get; set; }
public string Role1 { get; set; }
public virtual ICollection<EmployeeRole> EmployeeRole { get; set; }
}
public async Task<IActionResult> Index()
{
return View(await _context.Employee.Include(a=>a.EmployeeRole.Select(r=>r.Role)).ToListAsync());
}
I have a problem with my delete action, I'm getting this exception :
A first chance exception of type
'System.Data.Entity.Infrastructure.DbUpdateException' occurred in
EntityFramework.dll
Additional information: Entities in 'Model1Container.PublicationSet'
participate in the 'PublicationQuartier' relationship. 0 related
'Quartier' were found. 1 'Quartier' is expected.
Here my Delete Action :
[HttpPost]
public ActionResult DeleteOffreLocation(int id, OffreLocation offreLocation)
{
try
{
db.Entry(offreLocation).State = System.Data.Entity.EntityState.Deleted;
db.SaveChanges();
return RedirectToAction("ListOffreLocation");
}
catch
{
return View();
}
}
"OffreLocation" Model :
public partial class OffreLocation : Publication
{
public OffreLocation()
{
this.Locataire = new HashSet<Locataire>();
this.DemandeLocation = new HashSet<DemandeLocation>();
this.DemandeLocation1 = new HashSet<DemandeLocation>();
this.DemandeLocation2 = new HashSet<DemandeLocation>();
this.DemandeLocation3 = new HashSet<DemandeLocation>();
}
public string OffreLocation_TypeLog { get; set; }
public string OffreLocation_Sante { get; set; }
public double OffreLocation_Loyer { get; set; }
public System.DateTime OffreLocation_DateDisponibilite { get; set; }
public double OffreLocation_Superficie { get; set; }
public short OffreLocation_NbreChambre { get; set; }
public short OffreLocation_NbrePieces { get; set; }
public virtual ICollection<Locataire> Locataire { get; set; }
public virtual Proprietaire Proprietaire { get; set; }
public virtual ICollection<DemandeLocation> DemandeLocation { get; set; }
public virtual ICollection<DemandeLocation> DemandeLocation1 { get; set; }
public virtual ICollection<DemandeLocation> DemandeLocation2 { get; set; }
public virtual ICollection<DemandeLocation> DemandeLocation3 { get; set; }
}
"Publication" Model:
public partial class Publication
{
public Publication()
{
this.Photo = new HashSet<Photo>();
}
public int Publication_ID { get; set; }
public string Publication_Statut { get; set; }
public bool Publication_Meublee { get; set; }
public string Publication_Descriptif { get; set; }
public bool Publication_ContactParAgence { get; set; }
public double Publication_Maps_Latitude { get; set; }
public double Publication_Maps_Longitude { get; set; }
public virtual Quartier Quartier { get; set; }
public virtual ICollection<Photo> Photo { get; set; }
}
and finaly here my DB Container:
public partial class Model1Container : DbContext
{
public Model1Container()
: base("name=Model1Container")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public DbSet<Utilisateur> UtilisateurSet { get; set; }
public DbSet<Abonnement> AbonnementSet { get; set; }
public DbSet<AbonnementHistorique> AbonnementHistoriqueSet { get; set; }
public DbSet<ColocataireIdeal> ColocataireIdealSet { get; set; }
public DbSet<Publication> PublicationSet { get; set; }
public DbSet<Quartier> QuartierSet { get; set; }
public DbSet<Ville> VilleSet { get; set; }
public DbSet<RegionProvince> RegionProvinceSet { get; set; }
public DbSet<Photo> PhotoSet { get; set; }
public DbSet<MessageLocation> MessageLocationSet { get; set; }
public DbSet<MessageColocation> MessageColocationSet { get; set; }
public System.Data.Entity.DbSet<COM.MENNILIK.Models.Locataire> Locataires { get; set; }
public System.Data.Entity.DbSet<COM.MENNILIK.Models.OffreLocation> OffreLocations { get; set; }
}
Actually you need to remove the object passed to the view. You can either use id or your model OffreLocation. I will give you an example with id.
[HttpPost]
public ActionResult DeleteOffreLocation(int id, OffreLocation offreLocation)
{
try
{
var offreLocationGetById =db.OffreLocations.Find(id);
if(offreLocationGetById!=null)
db.OffreLocations.Remove(offreLocationGetById);
db.SaveChanges();
return RedirectToAction("ListOffreLocation");
}
catch
{
return View();
}
}
I will suggest also you comment your OnModelCreating as you are not using FluentApi code and beside you throw an Exception. It is a suggestion.
it seems to be a model validation error. I'm quite sure that Quartier is required and in the offreLocation from your Action, Quartier should be null.
so you have to :
populate Quartier, or
disable validation.