I am doing a college project and my knowledge in ASP.Net is not very deep. In my project I came across a MxM relationship and I can not implement this situation in a useful way. The relationship is as follows:
-
A company registers one or more garbage collection points and at the time of registration it chooses one or more garbage type accepted in your collection point.
-
A type of garbage can be used in the collection of various collection points.
-
A collection point can associate various types of garbage that are accepted.
I have tried in many ways indicated here on this site. I have tried here and creating the associative class manually, but in scaffolding Entity does not generate the relation in the view.
Doing as indicated at this link Here , The Entity Framework generated the associative table automatically, but in scaffolding the views were created with no association. In 1xN relations Entity automatically creates a dropdowlist
to be selected in the view.
In the MxM relation you should not automatically create a group of
checkbox
or a selection list? (or I'm expecting too much from the
Entity ...).
If you can not generate this feature automatically, how would you do it This?
After generating the checkbox group or selection list, how do to manipulate the associative table? (the table of the class in question Entity has already created CRUD).
Follow the code:
[Table("PontoDeColeta")]
public class PontoDeColeta
{
public PontoDeColeta()
{
TipoDeLixo = new HashSet<TipoDeLixo>();
}
public int Id { get; set; }
[Required(ErrorMessage = "O prenchimento é obrigatório")]
[Display(Name = "Nome popular*: ")]
public string NomePopular { get; set; }
[Required(ErrorMessage = "O prenchimento é obrigatório")]
[Display(Name = "Endereço do ponto de coleta*: ")]
public string Endereco { get; set; }
//Armazena usuário logado
[HiddenInput(DisplayValue = false)]
public string UsuarioResponsavel { get; set; }
public ICollection<TipoDeLixo> TipoDeLixo { get; set; }
}
[Table("TipoDeLixo")]
public class TipoDeLixo
{
public TipoDeLixo()
{
PontoDeColeta = new HashSet<PontoDeColeta>();
}
//[Key]
//[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required(ErrorMessage ="O prenchimento é obrigatório")]
[Display(Name = "Nome do tipo de lixo*: ")]
public string NomeTipoLixo { get; set; }
[Display(Name = "Este tipo de lixo está ativo? ")]
public bool Ativo { get; set; }
public ICollection<PontoDeColeta> PontoDeColeta { get; set; }
}
Edit : Following the best response of the comment, I had to change my classes besides creating the associative class manually.
public class TipoDeLixo{
public Guid Id { get; set; }
[Required(ErrorMessage ="O prenchimento é obrigatório")]
[Display(Name = "Nome do tipo de lixo*: ")]
public string NomeTipoLixo { get; set; }
[Display(Name = "Este tipo de lixo está ativo? ")]
public bool Ativo { get; set; }
public ICollection<PontoDeColetaTipoDeLixo> PontosDeColetaTiposDeLixo { get; set; }
}
public class PontoDeColeta{
public Guid Id { get; set; }
[Required(ErrorMessage = "O prenchimento é obrigatório")]
[Display(Name = "Nome popular*: ")]
public string NomePopular { get; set; }
public ICollection<PontoDeColetaTipoDeLixo> PontosDeColetaTiposDeLixo { get; set; }
}
public class PontoDeColetaTipoDeLixo{
public Guid Id { get; set; }
public virtual TipoDeLixo TipoDeLixo { get; set; }
public Guid TipoDeLixoId { get; set; }
public virtual PontoDeColeta PontoDeColeta { get; set; }
public Guid PontoDeColetaId { get; set; }
}
In the Create View of the PointCollect:
@Html.Partial("_TiposDeLixo",Model.PontosDeColetaTiposDeLixo)
I created the PartialView _LipType with the content:
@model IEnumerable<IdentitySample.Models.PontoDeColetaTipoDeLixo>
<div class="actions">
<a class="btn btn-default btn-sm" id="adicionar-tipo-de-lixo">
Adicionar Tipo de lixo
</a>
<script type="text/javascript">
$("#adicionar-tipo-de-lixo").click(function () {
$.get('/PontosDeColeta/NovaLinhaDeTipoDeLixo', function (template) {
$("#area-tipos-de-lixo").append(template);
});
});
</script>
</div>
<div id="area-tipos-de-lixo">
@if (Model != null)
{
foreach (var lixo in Model)
{
@Html.Partial("_LinhaTipoDeLixo", lixo);
}
}
</div>
Then I created the PartiaView _LineTypeLine with the content:
@model IdentitySample.Models.PontoDeColetaTipoDeLixo
@using (Html.BeginCollectionItem("TipoDeLixo"))
{
<div class="form-group">
@Html.HiddenFor(model => model.Id)
@Html.HiddenFor(model => model.TipoDeLixoId)
<label class="col-md-1 control-label">Nome</label>
<div class="col-md-5">
@Html.TextBoxFor(model => model.TipoDeLixo.NomeTipoLixo, new { @class = "form-control", placeholder = "Nome" })
@Html.ValidationMessageFor(model => model.TipoDeLixo.NomeTipoLixo, "", new { @class = "text-danger" })
</div>
<div class="col-md-2">
<a class="btn red" onclick="$(this).parent().parent().remove();">Excluir</a>
</div>
</div>
}
And in the PointCollectorController I created Action with the following content:
public ActionResult NovaLinhaDeTipoDeLixo()
{
return PartialView("_TiposDeLixo", new PontoDeColetaTipoDeLixo { Id = Guid.NewGuid() });
}
So when I run the system, the following error appears:
The model item passed into the dictionary is of type 'IdentitySample.Models.ColumnPart', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable'1 [IdentitySample.Models.ColumnTypeType] '.
EDIT : I took a print from the screen with the error. CONTROLLERUPDATEFullControllerCollection:
namespaceIdentitySample.Controllers{publicclassPontosDeColetaController:Controller{privateApplicationDbContextdb=newApplicationDbContext();//GET:PontosDeColetapublicActionResultIndex(){returnView();}publicActionResultNovaLinhaDeTipoDeLixo(){returnPartialView("_LinhaTipoDeLixo", new PontoDeColetaTipoDeLixo { Id = Guid.NewGuid() });
}
//Lista os potos de coleta de acordo com parametros passados
public JsonResult Listar(string searchPhrase, int current = 1, int rowCount = 5)
{
var Identificacao = User.Identity.GetUserId().ToString();
var Pontos = (from u in db.PontoDeColeta
where u.UsuarioResponsavel == Identificacao
select u);
string Chave = Request.Form.AllKeys.Where(v => v.StartsWith("sort")).First();
string Ordenacao = Request[Chave];
string Coluna = Chave.Replace("sort[", String.Empty).Replace("]",String.Empty);
var Soma = Pontos.Count();
if (!String.IsNullOrWhiteSpace(searchPhrase))
{
Pontos = Pontos.Where("NomePopular.Contains(@0) OR Endereco.Contains(@0) OR Cidade.Contains(@0) OR Estado.Contains(@0) OR Apelido.Contains(@0)", searchPhrase);
}
string ColunaOrdenacao = String.Format("{0} {1}", Coluna, Ordenacao);
var PontoDeColetaPagina = Pontos.OrderBy(ColunaOrdenacao).Skip((current - 1) * rowCount).Take(rowCount);
return Json(new{
rows = PontoDeColetaPagina.ToList(),
current = current,
rowCount = rowCount,
total = Soma
}
, JsonRequestBehavior.AllowGet);
}
// GET: PontosDeColeta/Details/5
public ActionResult Details(Guid? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
PontoDeColeta pontoDeColeta = db.PontoDeColeta.Find(id);
if (pontoDeColeta == null)
{
return HttpNotFound();
}
return PartialView(pontoDeColeta);
}
// GET: PontosDeColeta/Create
public ActionResult Create()
{
var UsuarioLogado = new PontoDeColeta();
UsuarioLogado.UsuarioResponsavel = User.Identity.GetUserId();
return View(UsuarioLogado);
}
// POST: PontosDeColeta/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,NomePopular,Endereco,Cidade,Estado,Latitude,Longitude,Remuneracao,InfoAdicional,Ativo,Apelido,UsuarioResponsavel")] PontoDeColeta pontoDeColeta)
{
if (ModelState.IsValid)
{
pontoDeColeta.Id = Guid.NewGuid();
db.PontoDeColeta.Add(pontoDeColeta);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(pontoDeColeta);
}
// GET: PontosDeColeta/Edit/5
public ActionResult Edit(Guid? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
PontoDeColeta pontoDeColeta = db.PontoDeColeta.Find(id);
if (pontoDeColeta == null)
{
return HttpNotFound();
}
pontoDeColeta.UsuarioResponsavel = User.Identity.GetUserId();
return View(pontoDeColeta);
}
// POST: PontosDeColeta/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Id,NomePopular,Endereco,Cidade,Estado,Latitude,Longitude,InfoAdicional,Ativo,Apelido,UsuarioResponsavel")] PontoDeColeta pontoDeColeta)
{
if (ModelState.IsValid)
{
db.Entry(pontoDeColeta).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(pontoDeColeta);
}
// GET: PontosDeColeta/Delete/5
public ActionResult Delete(Guid? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
PontoDeColeta pontoDeColeta = db.PontoDeColeta.Find(id);
if (pontoDeColeta == null)
{
return HttpNotFound();
}
return PartialView(pontoDeColeta);
}
// POST: PontosDeColeta/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(Guid id)
{
PontoDeColeta pontoDeColeta = db.PontoDeColeta.Find(id);
db.PontoDeColeta.Remove(pontoDeColeta);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}