Entity framework MVC 2实体框架视图模型插入

Entity framework MVC 2实体框架视图模型插入,entity-framework,asp.net-mvc-2,Entity Framework,Asp.net Mvc 2,这让我快发疯了。希望我的问题有意义 我正在使用MVC2和EntityFramework1,并试图插入一个带有两个导航属性的新记录 我有一个SQL表Categories,它有一个查找表categoritypes和另一个自引用查找categorityparent。EF在我的类别模型上创建了两个nav属性,一个称为Parent,另一个称为CategoryType,这两个属性都是各自模型的实例 在创建新类别的视图中,我有两个下拉列表,一个用于CategoryType,另一个用于ParentCategor

这让我快发疯了。希望我的问题有意义

我正在使用MVC2和EntityFramework1,并试图插入一个带有两个导航属性的新记录

我有一个SQL表Categories,它有一个查找表categoritypes和另一个自引用查找categorityparent。EF在我的类别模型上创建了两个nav属性,一个称为Parent,另一个称为CategoryType,这两个属性都是各自模型的实例

在创建新类别的视图中,我有两个下拉列表,一个用于CategoryType,另一个用于ParentCategory。当我尝试在没有ParentCategory的情况下插入新类别时(ParentCategory允许空值),一切都很好。我一添加ParentCategory,插入就失败了,奇怪的是(或者我认为是这样)以错误的形式抱怨CategoryType:

找到0个相关的“CategoryTypes”。应为1个“类别类型”

当我逐步完成时,我可以验证action方法参数中的两个ID属性是否正确。我还可以验证,当我去db获取带有ID的CategoryType和ParentCategory时,记录被很好地提取出来。但它在SaveChanges()上失败

我所能看到的是,在我看来,我的CategoryParent dropdownlistfor某种程度上导致了插件爆炸

请在我的httpPost创建操作方法中查看我的评论

我的视图模型如下所示:

public class EditModel
{
    public Category MainCategory { get; set; }
    public IEnumerable<CategoryType> CategoryTypesList { get; set; }
    public IEnumerable<Category> ParentCategoriesList { get; set; }
}
// 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>

<% } %>
我还注释掉了我的两个DropDownList,这样“mainCategory”上的属性就不会被实例化


因此,现在2个nav属性为空,我使用两个文本作为Id,它可以完美地工作。最后,我想使用mainCategory中父级和CategoryType的Id,但这似乎不起作用。可能是我不知道的一个很好的原因?

您是否尝试将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);

在设置CategoryType并毫无疑问地确认属性已填充之后,是否设置了断点?嗨,Dave。是的,我可以通过断点确认mainCategory.CategoryType仅使用表单提交中的Id填充,然后使用_db.CategoryTypeSet调用中的父类别填充。在设置
CategoryType之前,请尝试调用
AddToCategorySet
;那有用吗?嘿,克雷格。我的类别上的CategoryType不可为null,因此这会导致无法插入null值错误。我觉得我必须告诉你,你在这里的其他帖子已经帮助了我很多次,所以谢谢!当我的操作方法参数maincography.Parent从我的表单帖子或在我的控制器中实例化时,不知何故会导致此错误。我开始认为它与强类型html帮助程序有某种联系,就像我以前在MVC1中所做的那样,没有任何问题。否则我就忽略了一些非常愚蠢的事情。你仍然需要设置
CategoryType
。只需先调用
AddToCategorySet
。只要在调用
SaveChanges
之前设置
CategoryType
,就不会出现空错误。我确实喜欢这种为EF 1.0版添加外键的方式,但不幸的是,它在插入时的行为与此相同,但只有在我添加CategoryType和父类别时才会出现。如果省略父类别,两种方法都可以。你的方式肯定是最有效的。请看我的编辑,忘记告诉我你必须将父级和CategoryType设置为null,这样就不会有引用问题,他们可能会有Welp,这就成功了!!!我基本上就是按照你说的做的,认为我必须把那些导航属性设置为null有点奇怪。但它是有效的!在我的编辑方法中,我不必为这些属性设置空值,所以我想这只适用于插入。无论如何,谢谢你,妈妈。。。还有所有尝试过的人!
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);