MVC Entity Framework модифицирует дочерние объекты

Я довольно новичок в использовании MVC3 и EF4, и я пытаюсь реализовать функции CRUD набора родительских и дочерних объектов, однако я не нашел пример некоторых конкретных требований, которые мне нужны, и поэтому я хотел бы немного Помогите.

Ситуация у меня такова, что у меня есть Product сущность, которая имеет ребенка Category юридические лица. У меня все функции CRUD работают нормально для Product сущность и функциональность деталей, работающих с Category сущность в пределах Product подробный вид. Однако мне нужно осуществить добавление и удаление ребенка Categories из данного Product,

Обычно это не будет большой проблемой, но в этом случае, когда пользователь добавляет Category к Product Мне нужно только позволить пользователю иметь возможность выбирать из списка всех доступных Categories из базы данных. Пользователь также сможет удалить любого существующего потомка Categories из Product,

Я ожидаю, что реализация DropDownList со всеми неиспользованными "категориями" будет работать хорошо, однако я не знаю, как использовать один, чтобы позволить пользователю добавлять и удалять "категории", а затем сохранять изменения в базе данных через EF.

Кто-нибудь получил какие-либо предложения / примеры, как это сделать?

Если требуется дополнительная информация, пожалуйста, спросите.

Спасибо большое.

1 ответ

Решение

Я сделал то же самое с авторами и книгами, связанными многими со многими. Основная идея состоит в том, чтобы создать объект JSON из представления, в котором содержатся все авторы, и передать его в контроллер. Я также использовал jQuery UI TagIt, чтобы позволить пользователю добавлять / удалять авторов, связанных с книгой. Когда пользователь нажимает кнопку "Сохранить книгу", сценарий создает объект JSON, который имитирует объект "Книга".

Ниже приведен код. Пожалуйста, убедитесь, что вы добавили "json2.js" и "tagit.js" в проект, прежде чем пытаться использовать этот код.

Посмотреть модели:

 public class BookViewModel
    {
        public string Title { get; set; }
        public int BookId { get; set; }
        public int IsAvail { get; set; }
        public string CallNumber { get; set; }
        //Assiged authors
        public List<AuthorViewModel> Authors { get; set; }
        //available authors
        public List<AuthorViewModel> AuthorOptions { get; set; }
     }

    public class AuthorViewModel
    {
        public int AuthorId { get; set; }
        public string FirstName { get; set; }
    }

Код для книги /Edit.chtml:

@using System.Web.Script.Serialization
@model eLibrary.Models.BookViewModel

@{
    ViewBag.Title = "Edit";
}

<h2>Edit</h2>

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@*This is for JSON*@
<script src="../../Scripts/json2.js" type="text/javascript"></script>
<script src="../../Scripts/tagit.js" type="text/javascript"></script>
 @*These are for styling Control*@
<link href="../../Content/themes/base/jquery.ui.all.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">

    //This function is used for sending data(JSON Data) to BookController
    function BookSave() {
        // Step 1: Read View Data and Create JSON Object

        var author = { "AuthorId": "", "FirstName": "" };
        // Creating book Json Object
        var book = { "BookId": "", "Title": "", "IsAvail": "", "CallNumber":"", "authors": []};

        // Set Boook  Value
        book.BookId = $("#BookId").val();
        book.Title = $("#Title").val();
        book.IsAvail = $("#IsAvail").val();
        book.CallNumber = $("#CallNumber").val()  ;

        var tags = $('#authors').tagit('tags');

        for (var i in tags) {

            author.AuthorId = tags[i].value;
            author.FirstName = tags[i].label;

            book.authors.push(author );

            author = { "AuthorId": "", "FirstName": "" };

        }

        // Step 1: Ends Here
        // Set 2: Ajax Post
        // Here i have used ajax post for saving/updating information
        $.ajax({
            url: '/Book/Edit',
            data: JSON.stringify(book),
            type: 'POST',
            contentType: 'application/json;',
            dataType: 'json',
            success: function (result) {

                if (result.Success == "1") {
                    window.location.href = "/Book/Edit";
                }
                else {
                    alert(result.ex);
                }
            }
        });

    }

    </script>

@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Book Details</legend>

        @Html.HiddenFor(model => model.BookId)

        <div class="editor-label">
            @Html.LabelFor(model => model.Title)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Title)
            @Html.ValidationMessageFor(model => model.Title)
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.IsAvail)
        </div>
            @Html.EditorFor(model => model.IsAvail)
            @Html.ValidationMessageFor(model => model.IsAvail)

        @Html.EditorFor(model => model.CallNumber);
    </fieldset>

@Html.Partial("AuthorsByBook", Model.Authors, new ViewDataDictionary { { "mode", "EDIT" } })        

    <input type="button" value="Book Save" onclick="BookSave()" />
}

Код для Книги /AuthorsByBook.chtml

@model IEnumerable< eLibrary.Models.AuthorViewModel>
<link href="../../Content/tagit-awesome-blue.css" rel="stylesheet" type="text/css" />
     <div class="box">
       <ul id="authors" name="authors">

    </ul>
    </div>
<script type="text/javascript">


//Load authors in the javascript variable
    $(function () {
      var initialAuthorList=[];

      @if(ViewData["mode"]=="EDIT")
{      

   foreach (var category in Model)
   {

        <text>

        initialAuthorList.push({label: "@category.FirstName", value: @category.AuthorId });
        </text>

 }
 }

  $('#authors').tagit({tagSource: function (request, response) {

                    $.ajax({

                        url: "/Author/SearchAuthor", type: "POST", dataType: "json",

                        data: { searchText: request.term, maxResults: 10 },
                        success: function (data) {
                            response($.map(data, function (item) {

                                return { label: item.FirstName, value: item.AuthorId }
                            }))
                        }
                    })
                },

    initialTags:initialAuthorList,minLength:3,allowNewTags:false,sortable:true,delay:400});

    });
    </script>

Код для BookController.cs

public ActionResult Edit(int id)
        {
            //To DO: use repository to fetch data
            Book  book = db.Books.Single(a => a.BookId  == id);
            Mapper.CreateMap<Book, BookViewModel>();
            Mapper.CreateMap<Author, AuthorViewModel>();
            BookViewModel bookVm = Mapper.Map<Book, BookViewModel>(book);
            List<AuthorViewModel> Authors = Mapper.Map<List<Author>,List<AuthorViewModel>>( db.Authors.ToList());
            bookVm.AuthorOptions = Authors;
            return View(bookVm);
        }



[HttpPost]
        public ActionResult Edit(BookViewModel bookv)
        {
            //create maps
            Mapper.CreateMap<AuthorViewModel, Author>();
            Mapper.CreateMap<BookViewModel, Book>();

            //convert view objects to model objects
            Book book = Mapper.Map<BookViewModel, Book>(bookv);
            List<Author> authors = Mapper.Map<List<AuthorViewModel>, List<Author>>(bookv.Authors.ToList());

            //this has to be executed before db.Books.Attach
            //clear authors
            book.Authors.Clear();

            db.Books.Attach(book);

            //assign authors to book
            foreach (Author a in authors) { db.Authors.Attach(a); }

            book.Authors.Clear();

            foreach (Author a in authors) { book.Authors.Add(a); }


        db.ObjectStateManager.ChangeObjectState(book, EntityState.Modified);
        db.SaveChanges();
        return RedirectToAction("Index");

    }

Код для метода SearchAuthor в AuthorController.cs

public JsonResult SearchAuthor(string searchText, int? maxResults)
        {
            IEnumerable<Author> query = db.Authors;
            searchText = searchText.ToLower();
            query = query.Where(c => c.FirstName.ToLower().Contains(searchText));

            if ((maxResults ?? 0) == 0)
            {
                return Json(query.ToList());
            }
            else
            {
                return Json(query.Take((int)maxResults).ToList());
            }
        }
Другие вопросы по тегам