在 Asp.Net MVC 中实体作为模型出现“EntityCollection 已初始化”错误?

2023-12-22

我在创建一个复杂的对象时遇到了很大的困难。我有一个带有顾问表的 EF 模型,该表与许多其他表具有一对多关系。我想按原样使用 Consultant 对象作为模型,因为它非常简单(正如 NerdDinner 教程中所做的那样),就像我对其他没有一对多关系的对象所做的那样。问题是,当我尝试发布到 Create 方法时,这些关系会导致此错误:“EntityCollection 已初始化”。

有几个人建议我改用 ViewModel,我发布了一个关于此的问题(MVC 中的 ViewModel 和与实体框架的一对多关系? https://stackoverflow.com/questions/5083880/viewmodels-and-one-to-many-relationships-with-entity-framework-in-mvc)因为我不太明白。问题是代码变得非常荒谬...这与我迄今为止所欣赏的 MVC 的简单性相去甚远。

在那个问题中,我忘记提及除了 Create 方法之外,Edit 方法还使用相同的 CreateConsultant 方法(名称可能会产生误导,它实际上填充 Consultant 对象)。因此,为了不在编辑时添加额外的“程序”,我需要使该方法进一步复杂化。所以现在看起来像这样:

private Consultant CreateConsultant(ConsultantViewModel vm, Consultant consultant) //Parameter Consultant needed because an object may already exist from Edit method.
        {
            consultant.Description = vm.Description;
            consultant.FirstName = vm.FirstName;
            consultant.LastName = vm.LastName;
            consultant.UserName = User.Identity.Name;

            if (vm.Programs != null)
                for (int i = 0; i < vm.Programs.Count; i++)
                {
                    if (consultant.Programs.Count == i)
                        consultant.Programs.Add(vm.Programs[i]);
                    else
                        consultant.Programs.ToList()[i] = vm.Programs[i];
                }
            if (vm.Languages != null)
                for (int i = 0; i < vm.Languages.Count; i++)
                {
                    if (consultant.Languages.Count == i)
                        consultant.Languages.Add(vm.Languages[i]);
                    else
                        consultant.Languages.ToList()[i] = vm.Languages[i];
                }
            if (vm.Educations != null)
                for (int i = 0; i < vm.Educations.Count; i++)
                {
                    if (consultant.Educations.Count == i)
                        consultant.Educations.Add(vm.Educations[i]);
                    else
                        consultant.Educations.ToList()[i] = vm.Educations[i];
                }
            if (vm.WorkExperiences != null)
                for (int i = 0; i < vm.WorkExperiences.Count; i++)
                {
                    if (consultant.WorkExperiences.Count == i)
                        consultant.WorkExperiences.Add(vm.WorkExperiences[i]);
                    else
                        consultant.WorkExperiences.ToList()[i] = vm.WorkExperiences[i];
                }

            if (vm.CompetenceAreas != null)
                for (int i = 0; i < vm.CompetenceAreas.Count; i++)
                {
                    if (consultant.CompetenceAreas.Count == i)
                        consultant.CompetenceAreas.Add(vm.CompetenceAreas[i]);
                    else
                        consultant.CompetenceAreas.ToList()[i] = vm.CompetenceAreas[i];
                }

            string uploadDir = Server.MapPath(Request.ApplicationPath) + "FileArea\\ConsultantImages\\";
            foreach (string f in Request.Files.Keys)
            {
                var filePath = Path.Combine(uploadDir, Path.GetFileName(Request.Files[f].FileName));
                if (Request.Files[f].ContentLength > 0)
                {
                    Request.Files[f].SaveAs(filePath);
                    consultant.Image = filePath;
                }

            }
            return consultant;
        }

这是荒谬的,这可能是由于我的无能,但我需要知道如何正确地做到这一点。仅回答“使用 ViewModel”显然是不够的,因为这就是让我陷入困境的原因。我希望简单的实体对象作为模型的简单性,但没有“EntityCollection 已初始化”错误。我该如何解决这个问题?

当然,如果我只是以错误的方式执行 ViewModel 策略,也欢迎提出建议,但主要是我想知道如果我以简单的“NerdDinner”简单对象方式执行此操作,会导致此错误。另请记住,相关视图仅限于网站的授权用户。我很乐意以“正确”的方式做到这一点,但如果使用 ViewModels 意味着代码很难维护,我会放弃它......

请帮忙!

UPDATE:

事实证明这段代码根本不起作用。我只是在调用编辑更新值后进行了检查,但它没有更新它们。所以只有创建部分有效。

这是不起作用的部分:

consultant.Programs.ToList()[i] = vm.Programs[i];

我有一种预感,我无法使用 ToList 并更新 EntityCollection 中的项目。但这使得事情变得更加困难。所以现在我不知道如何直接对实体进行操作,我更喜欢这样做(见上文)。我不知道如何让这个 ViewModel 的东西工作,更不用说让它干净了......

有任何想法吗?这里一定有什么真正的错误,我希望有人会发现我是如何错过了一些简单的东西,使所有这些代码都发生了转变!


好吧,根据我的经验,EF 的东西在线上使用时不容易很好地发挥作用,句号(也就是说,无论您是在 MVC 还是 WCF 或其他环境中,它都不是传递数据的好格式)。对我来说,这是一个 EF 问题,而不是 MVC 问题,因为您在直接使用 EF 模型时遇到的问题与它们在 EF 对象上下文中的跟踪方式有关。有人告诉我,有一些解决方案涉及重新附加传递的实体,但我发现这比它的价值更麻烦;和其他人一样,这就是为什么大多数人在这种情况下说“使用视图模型”作为输入参数。

我同意你上面的代码有点令人不快,有几种方法可以修复它。首先,检查一下自动映射器 http://automapper.codeplex.com/,这很有帮助,因为您可以跳过定义明显的内容(例如,当两个模型都有一个简单的属性,例如相同类型和名称的“Name”)。

其次,无论如何,你用循环所做的事情有点不对劲。您不应假设从客户端发布的列表与 EF 正在跟踪的列表(而是列表;指的是您的程序等)具有相同的顺序等。相反,请考虑可能发生的情况并考虑这些情况。我将使用程序作为示例。

1) 顾问有一个计划,但该计划的详细信息已更改。 2) 顾问在视图模型中没有程序 2a) 该程序已经存在于数据库中的某个地方,只是不属于该顾问的一部分 2b) 该程序是新的。 3)顾问有一个不在视图模型中的程序(您当前没有考虑到的东西)。

我不知道在每种情况下您希望发生什么(即,视图模型是完整且规范的,还是更新期间的实体模型?),但假设您正在循环查看视图模型的程序,因为您做上面的。对于场景 1(这似乎是您的主要问题),您将需要执行类似的操作(使用 AutoMapper):

var updated = vm.Programs[i];    
var original = consultant.Programs.SingleOrdefault(p=>p.ID == uppdated.ID);
Mapper.Map(updated,original);
yourEfContext.SaveChanges(); // at some point after this, doesn't have to be inside the loop

编辑: 另一种可能对您有用的想法是,当您从数据库中获取顾问时(不确定您使用什么机制),请确保您也对要更新的集合调用 Include 。否则,您所做的每一次迭代都将是到数据库的另一次往返,如果您只是使用 Include 一次性加载它们,显然您可以避免这种情况。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Asp.Net MVC 中实体作为模型出现“EntityCollection 已初始化”错误? 的相关文章

  • OutputCache 因复杂对象属性而异

    我有一个控制器操作 它接收一个复杂对象作为参数 我需要 OutputCache 根据该复杂对象的属性之一而变化 这可能吗 如何 如果你有一个像这样的模型 public class person public string Name get
  • ASP.Net 中的不同身份验证方式

    我正在为我的公司开发一个网站 该网站可以在我们的内部网络和互联网上访问 有人问我一些对我来说似乎不可能的问题 但我想在真正说之前问这个问题 我们公司有两种类型的用户 一种是实际在 Active Directory 中注册的用户 等等 拥有
  • 清洁琴弦的更好方法?

    我正在使用这种方法来清理字符串 public static string CleanString string dirtyString string removeChars lt gt string result dirtyString f
  • 如何在asp.net中的按钮单击事件调用之前和之后调用javascript函数

    我在 ASP NET 中创建了 ButtonClick 函数 如下所示
  • 复杂对象MVC3的JSON序列化

    我有一个问题 我似乎不知道如何序列化类型的对象 public class SchedulingCalendarMonth public List
  • 使用实体框架从 2 个表返回数据

    我正在使用 MVC3 和实体框架 但我需要来自不同表的更多数据 通常我会做这样的事情来从表中获取数据 Table Users id username 在代码中我会做这样的事情来获取所有用户 public static IEnumerable
  • 设置国际货币格式

    我有一个 asp net 应用程序 我们正在 全球化 过程中 我将 currentculture 和 currentUICultre 设置为适当的值 并且货币按预期使用货币格式显示 即 FormatCurrency nPrice 产生 en
  • 检测 ASP.NET MVC 上的会话过期

    我构建了一个购物车 它使用会话状态在用户浏览商店时保留购物车数据 我遇到一个问题 如果我在购物车的第 1 步上长时间打开浏览器窗口 然后按 转到第 2 步 我的操作会引发错误 因为第 2 步操作假定会话尚未过期并且ShopCart 对象处于
  • 将 MVC 站点部署到 IIS 会导致找不到默认共享部分视图

    我有一个可以在本地 IIS 上完美运行的网站 我的所有页面都使用默认的共享部分视图 这称为预期 Layout cshtml 该视图放置在我的共享文件夹中 这可以在这里看到 正如我所期望的那样 这非常有效 不过 我现在发布了我的网站 然后 我
  • 有没有办法在 ASP.net 中制作像 gmail 那样的进度条?

    有没有办法在 ASP net 中制作像 gmail 那样的进度条 以下是一些基于 ASP NET 的进度栏控件 ASP NET AJAX 进度条控件 http mattberseth com blog 2008 05 aspnet ajax
  • 使用 IIS 发布:找不到服务器 DNS

    我正在尝试使用 IIS 发布我的项目 我能够通过 Visual Studio 发布它 La aplicaci n web se public correctamente file D www plataformafantasy com Co
  • 如何在 ASP.Net 中检索上传文件的“上次修改日期”

    我正在开发一个网站 客户端在其中上传一些文档文件 如 doc docx htm html txt pdf 等 我想检索上传文件的最后修改日期 我创建了一个处理程序 ashx 来完成保存文件的工作 Following is the code
  • 使用 ASP.NET 控件而不进行数据绑定

    看来我使用 ASP NET 数据绑定太久了 以至于忘记了一些基础知识 我正在 ASPX 页面中动态创建一个表 无需数据绑定 foreach XXX x in TTTT gt tr td td tr
  • 如何将 Razor 视图转换为字符串?

    我想使用我的 Razor 视图作为某种发送电子邮件的模板 所以我想将我的模板 保存 在视图中 将其作为字符串读入控制器 进行一些必要的替换 然后发送它 我有有效的解决方案 我的模板作为 HTML 页面托管在某处 但我想将其放入我的应用程序中
  • 如何从源视图 (aspx) 中的 C# 中为按钮事件添加事件处理程序

    为 HTML 源视图中的按钮创建代码隐藏 webforms 事件处理程序的最简单方法是什么 在 VB NET 中 切换到代码隐藏页面并使用顶部的对象和事件组合框来选择和创建非常容易 在 C 中 这些都缺失了 我真的不喜欢设计视图 确保 属性
  • 如何使用 JavaScript 中的值填充下拉列表?

    我在 Tridion CMS 扩展中的功能区工具栏按钮中添加了一个按钮 单击该按钮后 将显示一个弹出页面 其中包含两个下拉菜单 通过更改第一个下拉控件中的值 我应该填充第二个下拉控件的值 就我而言 我正在使用ASP drop down li
  • Html Helper“操作”未定义,Asp.NET Core 2.2

    我是 ASP NET Core MVC 的新手 我会在这个问题前说我已经阅读了其他类似的问题 但它们与我遇到的问题并不完全相同 我正在尝试实现动态左侧导航 其中每个按钮都是从我的数据库加载的 当我打电话时 Html Action NavMe
  • 检查缓存后 System.Web.HttpContext.Current 自身为空

    今天我遇到了一个奇怪的问题 这对我来说毫无意义 总结如下 在方法内部 我检查缓存的项目 如下所示 private async Task
  • Glimpse HUD 和 SQL 选项卡中的数据库查询计数之间存在差异

    这个问题涉及 Glimpse MVC3 和 Glimpse EF5 包 我正在尝试调试旧 MVC3 站点上的性能问题 根据一瞥HUD 一个特定的 GET 请求有12查询于28ms总计 但是当我展开打开主面板并单击SQL Tab 它说只有6查
  • 显示异常时的自定义错误消息:从客户端检测到潜在危险的 Request.Form 值

    我在我的 Web 应用程序中使用 ASP NET 的登录控件 当发生此异常时 我想在标签上显示一种有趣的错误类型System Web HttpRequestValidationException A potentially dangerou

随机推荐