Working with ManyToMany relations

3 posts, 0 answers
  1. Mikael
    Mikael avatar
    6 posts
    Member since:
    Feb 2013

    Posted 17 Feb 2013 Link to this post

     I'v finally been able to do som more work with Kendo and have been fiddling more with my ManyToMany relations. I'v set ut a test project with a two really simple models Movies and Actors
    [Table("Movies")]
        public class Movie
        {
            [Key]
            [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
            public int MovieId { getset; }
            public string Name { getset; }
            public List<Actor> Actors { getset; }
        }
    And
    [Table("Actor")]
        public class Actor
        {
            [Key]
            [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
            public int ActorId { getset; }
            public string Name { getset; }
            [ScriptIgnore]
            public List<Movie> Movies { getset; }
        }
    Code first migrations have kindly generated a ActorMovie table for me in the database and using normal MVC4 controllers and views this is working as expected. I'm able to both add one or more actors to a movie. And add one or movie to an actors.

    Now, I would like to be able to display the lists of Actors or Movies in the row of the respective Movie or Actor in a Grid.
    I'd also like to be able to add both Actors and Movies (one or more) using an editable Grid.

    Since the Grid build up and controllers will be the same for both I'm only going to add the code for the movies.
    This is my Grid so far:
    @(Html.Kendo().Grid<KendoUi.ViewModels.MovieViewModel>()
        .Name("Grid")
        .Columns(columns =>
        {
            columns.Bound(p => p.MovieId);
            columns.Bound(p => p.Name);
            columns.ForeignKey(p => p.Actors, (System.Collections.IEnumerable)ViewBag.Actors, "ActorId", "Name");
            columns.Command(command => { command.Edit(); command.Destroy(); }).Width(180);
        })
        .ToolBar(toolbar => toolbar.Create())
        .Editable(editable => editable.Mode(GridEditMode.InLine))
        .Pageable()
        .Sortable()
        .Scrollable()
        .DataSource(dataSource => dataSource
            .Ajax()
            .Events(events => events.Error("error_handler"))
            .Model(model =>
                {
                    model.Id(p => p.MovieId);
                    model.Field(p => p.MovieId).Editable(false);
                })
            .Create(update => update.Action("EditingInline_Create", "Movie"))
            .Read(read => read.Action("EditingInline_Read", "Movie"))
            .Update(update => update.Action("EditingInline_Update", "Movie"))
            .Destroy(update => update.Action("EditingInline_Destroy", "Movie"))
            )
    )
    And this is my controller:
    public class MovieController : Controller
        {
            private readonly KendoContext context;
     
            public MovieController()
            {
                context = new KendoContext();
            }
     
            public ActionResult Index()
            {
                ViewBag.Actors = context.Actors;
                return View();
            }
     
     
            public ActionResult EditingInline_Read([DataSourceRequest] DataSourceRequest request)
            {
                return Json(context.Movies.Include("Actors").ToDataSourceResult(request));
            }
     
            [AcceptVerbs(HttpVerbs.Post)]
            public ActionResult EditingInline_Create([DataSourceRequest] DataSourceRequest request, MovieViewModel movie)
            {
                if (movie != null && ModelState.IsValid)
                {
                    var toAdd = new Movie() {Name = movie.Name};
                    context.Entry(toAdd).State = EntityState.Added;
                    context.SaveChanges();
                }
                return Json(new[] { movie }.ToDataSourceResult(request, ModelState));
            }
     
            [AcceptVerbs(HttpVerbs.Post)]
            public ActionResult EditingInline_Update([DataSourceRequest] DataSourceRequest request, MovieViewModel movie)
            {
                if (movie != null && ModelState.IsValid)
                {
                    var target = context.Movies.Single(x => x.MovieId == movie.MovieId);
                    if (target != null)
                    {
                        target.Name = movie.Name;
                        context.Entry(target).State = EntityState.Modified;
                        context.SaveChanges();
                    }
                }
                return Json(ModelState.ToDataSourceResult());
            }
     
            [AcceptVerbs(HttpVerbs.Post)]
            public ActionResult EditingInline_Destroy([DataSourceRequest] DataSourceRequest request, MovieViewModel movie)
            {
                if (movie != null)
                {
                    var target = context.Movies.Single(x => x.MovieId == movie.MovieId);
                    context.Entry(target).State = EntityState.Deleted;
                    context.SaveChanges();
                }
                return Json(ModelState.ToDataSourceResult());
            }
        }
    And finally the MovieViewModel(I realize that as the code is now, the MovieViewModel isn't necessary:
    public class MovieViewModel
        {
            public int MovieId { get; set; }
            public string Name { get; set; }
            public List<Actor> Actors { get; set; }
        }

    Since the logic to add ManyToMany relations are the same for MVC4 controllers using normal Views I assume I'm going to be able to use that code for this too.
    I just need som guidance into what changes I need to do to the actual Grid code and ViewModel to be able to retrieve the data needed from the Grid to add/remove objects in the controller.
  2. Daniel
    Admin
    Daniel avatar
    2118 posts

    Posted 20 Feb 2013 Link to this post

    Hello Mikael,

    The foreignkey column can be used for one to many relations. For many to many you could use an Grid Hierarchy or a custom editor that can update a collection of objects(source binding, another list component). 

    Regards,
    Daniel
    the Telerik team
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
  3. Kendo UI is VS 2017 Ready
  4. Mikael
    Mikael avatar
    6 posts
    Member since:
    Feb 2013

    Posted 20 Feb 2013 Link to this post

    Hello, thanks for the tips.
    I'll look into them both, since the related table, in this case, only contains a one field I think inserting a whole grid would be overkill.
    I haven't looked at building a custom editor yet, but if it could produce a Selectmany style selectbox that would fit perfect.
    I'll post back if I run into any problems later.

    Br.
Back to Top