Вставка модели представления Entity Framework MVC 2 - PullRequest
0 голосов
/ 31 марта 2010

Это сводит меня с ума. Надеюсь, мой вопрос имеет смысл ...

Я использую MVC 2 и Entity Framework 1 и пытаюсь вставить новую запись с двумя навигационными свойствами.

У меня есть таблица SQL, Категории, в которой есть таблица поиска CategoryTypes и другой самозависимый поиск CategoryParent. EF создает два свойства nav для моей модели Category, одно с именем Parent, а другое с CategoryType, оба экземпляра соответствующих моделей.

С моей точки зрения, которая создает новую категорию, у меня есть два раскрывающихся списка: один для типа категории, а другой для ParentCategory. Когда я пытаюсь вставить новую категорию БЕЗ ParentCategory, которая допускает нулевые значения, все в порядке. Как только я добавляю ParentCategory, вставка завершается неудачно, и странно (или я так думаю) жалуется на CategoryType в форме этой ошибки:

0 связанных "CategoryTypes" были найдены. 1 «CategoryTypes» ожидается.

Когда я прохожу, я могу убедиться, что оба свойства ID, входящие в параметр метода действия, верны. Я также могу убедиться, что когда я иду в базу данных, чтобы получить CategoryType и ParentCategory с идентификаторами, записи обрабатываются нормально. Тем не менее он не работает в SaveChanges ().

Все, что я вижу, это то, что мой раскрывающийся список CategoryParent для, на мой взгляд, каким-то образом вызывает вставку бомбы.

Пожалуйста, смотрите мои комментарии в моем методе действия httpPost Create.

Модель моего вида выглядит так:

public class EditModel
{
    public Category MainCategory { get; set; }
    public IEnumerable<CategoryType> CategoryTypesList { get; set; }
    public IEnumerable<Category> ParentCategoriesList { get; set; }
}

Мои методы действий Create выглядят так:

// GET: /Categories/Create
    public ActionResult Create()
    {
        return View(new EditModel()
        {
            CategoryTypesList = _db.CategoryTypeSet.ToList(),
            ParentCategoriesList = _db.CategorySet.ToList()
        });
    }

    // POST: /Categories/Create
    [HttpPost]
    public ActionResult Create(Category mainCategory)
    {
        if (!ModelState.IsValid)
            return View(new EditModel()
            {
                MainCategory = mainCategory,
                CategoryTypesList = _db.CategoryTypeSet.ToList(),
                ParentCategoriesList = _db.CategorySet.ToList()
            });

        mainCategory.CategoryType = _db.CategoryTypeSet.First(ct => ct.Id == mainCategory.CategoryType.Id);

        // This db call DOES get the correct Category, but fails on _db.SaveChanges().
        // Oddly the error is related to CategoryTypes and not Category.
        // Entities in 'DbEntities.CategorySet' participate in the 'FK_Categories_CategoryTypes' relationship.
        // 0 related 'CategoryTypes' were found. 1 'CategoryTypes' is expected.
        //mainCategory.Parent = _db.CategorySet.First(c => c.Id == mainCategory.Parent.Id);

        // If I just use the literal ID of the same Category,
        // AND comment out the CategoryParent dropdownlistfor in the view, all is fine.
        mainCategory.Parent = _db.CategorySet.First(c => c.Id == 2);

        _db.AddToCategorySet(mainCategory);
        _db.SaveChanges();

        return RedirectToAction("Index");
    }

Вот моя форма Создать на виде:

    <% using (Html.BeginForm()) {%>
    <%= Html.ValidationSummary(true) %>

    <fieldset>
        <legend>Fields</legend>

        <div>
            <%= Html.LabelFor(model => model.MainCategory.Parent.Id) %>
            <%= Html.DropDownListFor(model => model.MainCategory.Parent.Id, new SelectList(Model.ParentCategoriesList, "Id", "Name")) %>
            <%= Html.ValidationMessageFor(model => model.MainCategory.Parent.Id) %>
        </div>

        <div>
            <%= Html.LabelFor(model => model.MainCategory.CategoryType.Id) %>
            <%= Html.DropDownListFor(model => model.MainCategory.CategoryType.Id, new SelectList(Model.CategoryTypesList, "Id", "Name"))%>
            <%= Html.ValidationMessageFor(model => model.MainCategory.CategoryType.Id)%>
        </div>

        <div>
            <%= Html.LabelFor(model => model.MainCategory.Name) %>
            <%= Html.TextBoxFor(model => model.MainCategory.Name)%>
            <%= Html.ValidationMessageFor(model => model.MainCategory.Name)%>
        </div>

        <div>
            <%= Html.LabelFor(model => model.MainCategory.Description)%>
            <%= Html.TextAreaFor(model => model.MainCategory.Description)%>
            <%= Html.ValidationMessageFor(model => model.MainCategory.Description)%>
        </div>

        <div>
            <%= Html.LabelFor(model => model.MainCategory.SeoName)%>
            <%= Html.TextBoxFor(model => model.MainCategory.SeoName, new { @class = "large" })%>
            <%= Html.ValidationMessageFor(model => model.MainCategory.SeoName)%>
        </div>

        <div>
            <%= Html.LabelFor(model => model.MainCategory.HasHomepage)%>
            <%= Html.CheckBoxFor(model => model.MainCategory.HasHomepage)%>
            <%= Html.ValidationMessageFor(model => model.MainCategory.HasHomepage)%>
        </div>

        <p><input type="submit" value="Create" /></p>
    </fieldset>

<% } %>

Может, я слишком поздно ложился спать, играя с MVC 2? :) Пожалуйста, дайте мне знать, если я не достаточно ясно.

Некоторые вещи, которые я изменил с тех пор, как задали этот вопрос. Я думаю, что я близко?

Мой новый метод создания действия:

        private DbEntities _db = new DbEntities();

    // POST: /Categories/Create
    [HttpPost]
    public ActionResult Create(Category mainCategory)
    {
        if (!ModelState.IsValid)
            return View(new EditModel()
            {
                MainCategory = mainCategory,
                CategoryTypesList = _db.CategoryTypeSet.ToList(),
                ParentCategoriesList = _db.CategorySet.ToList()
            });

        int parentId = 2; // Accessories in db.
        short typeId = 1; // Product type in db.
        mainCategory.ParentReference.EntityKey = new EntityKey("DbEntities.CategorySet", "Id", parentId);
        mainCategory.CategoryTypeReference.EntityKey = new EntityKey("DbEntities.CategoryTypeSet", "Id", typeId);

        _db.AddToCategorySet(mainCategory);     
        _db.SaveChanges();

        return RedirectToAction("Index");
    }

Я также закомментировал два моих выпадающих списка, чтобы эти свойства в "mainCategory" не создавались.

Итак, теперь, когда свойства nav равны нулю, я использую два литерала для идентификатора, и он работает отлично. В конечном счете, я хочу использовать идентификаторы Parent и CategoryType из mainCategory, но это, похоже, не работает. Вероятно, веская причина, о которой я не знаю?

1 Ответ

1 голос
/ 31 марта 2010

Вы пытались установить EntityReference как

mainCategory.CategoryTypeReference.EntityKey = new EnityKey("YourEntities", "Id", mainCategory.CategoryType.Id);

таким образом, вам не нужно загружать ваш CategoryType, и это может решить вашу проблему.

РЕДАКТИРОВАТЬ : образец, который я разместил, не завершен, извините, вот что вы должны сделать

int parentId = mainCategory.Parent.Id; 
short typeId = mainCategory.CategoryType.Id;

mainCategory.Parent = null;
mainCategory.CategoryType = null;
mainCategory.ParentReference.EntityKey = new EntityKey("DbEntities.CategorySet", "Id", parentId); 
mainCategory.CategoryTypeReference.EntityKey = new EntityKey("DbEntities.CategoryTypeSet", "Id", typeId);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...