数据库中缺少Collection中的数据(ASP.NET MVC)

时间:2015-09-15 16:18:52

标签: c# asp.net asp.net-mvc asp.net-mvc-4

为了简单和测试,我从一个新项目中做到这一点,然后在我理解了问题后将其应用到我的实际项目中。

我创建了一个名为 Person 的模型,其中包含一个名为 ServiceNeeded 的List属性。前端用户可以根据需要编码尽可能多的服务,因此动态创建 ServiceNeeded 的输入字段。在POST方法中,这些字符串输入按预期绑定。我将 Person 对象保存到数据库中,并按预期工作。当我尝试从数据库中检索人物对象时,除了 ServicesNeeded 之外都存在。

这是我的代码

模型(Person.cs):

public class Person
{
    public Guid  Id { get; set; }
    public String Name { get; set; }
    public List<String> ServiceNeeded { get; set; }

    public Person()
    {
        this.ServiceNeeded = new List<String>();
    }
}

控制器(索引和[POST]创建方法):

    public ActionResult Index()
    {
        var x = db.People.ToList();
        return View(db.People.ToList());
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "Id,Name,ServiceNeeded")] Person person)
    {
        if (ModelState.IsValid)
        {
            person.Id = Guid.NewGuid();
            db.People.Add(person);

            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(person);
    }

正如我所说,ServicesNeeded的输入字段是动态创建的,但是正确绑定到模型。

以下是运行时的一些屏幕截图:

用户做一些输入后: enter image description here

我在Index返回View之前添加了一个变量来检查运行时: enter image description here

如图所示,存在相同的以及除 ServicesNeeded 之外的所有内容。我对ASP.NET MVC和Web开发一般都很新。我在项目中处理其他集合,尽管是对象的集合。只有这个特殊情况我不明白。我的错误在哪里?

3 个答案:

答案 0 :(得分:0)

如果未启用延迟加载,则需要告诉dbcontext加载引用。

首先将ServiceNeeded更改为虚拟财产

public virtual List<String> ServiceNeeded { get; set; }

然后在使用Include

下拉此人时加载该属性
var x = db.People.Include("ServiceNeeded").ToList();
return View(x);

关于加载相关实体的文章https://msdn.microsoft.com/en-us/data/jj574232.aspx

答案 1 :(得分:0)

查看数据库;是那里的记录?我认为问题是ServicesNeeded集合没有持久化到数据库;尝试添加:

[HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "Id,Name,ServiceNeeded")] Person person)
    {
        if (ModelState.IsValid)
        {
            person.Id = Guid.NewGuid();
            db.People.Add(person);

            foreach (var service in person.ServicesNeeded)
                 db.ServicesNeeded.Add(service);

            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View(person);
    }

我不相信附加到Person对象的关系会自动保留在SaveChanges()上,并且可能不会将其发送到数据库。

答案 2 :(得分:0)

我认为适合实体框架工作的最佳方法是为您的&#39; ServiceNeeded&#39;创建另一个Model,将其添加到您的&#39; DbContext&#39;中,保存所有服务相应的DbSet并使用.Include中的LINQ检索它们。在这篇冗长的介绍之后,请看下面的代码: 在您的模型中:

public class MyService{
    public Guid Id {get;set;}
    public string ServiceName {get;set;}
    public Guid PersonId {get;set;}
}
public class Person
{
    public Guid  Id { get; set; }
    public String Name { get; set; }
    public virtual IList<MyService> ServiceNeeded { get; set; }
}

在您的ApplicationDbContext中:

public System.Data.Entity.DbSet<MyService> MyServices { get; set; }
public System.Data.Entity.DbSet<Person> People { get; set; }

在你的POST ActionResult:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,Name,ServiceNeeded")] Person person, List<String> ServiceNeeded)
{
    if (ModelState.IsValid)
    {

        db.People.Add(person);
        db.SaveChanges();
        db.Entry(person).GetDatabaseValues();
         foreach (string service in ServiceNeeded){
             db.MyServices.Add( new MyService {ServiceName = service,
                   PersonId = person.Id})
        }
        db.SaveChanges();
        return RedirectToAction("Index");
    }

    return View(person);
}

请注意,我已移除person.Id = Guid.NewGuid();以便数据库身份生成Id ,然后我重新获取person.Id以便创建MyService记录。

最后正如@ JamieD77建议的那样,在你的GET ActionResult中:

public ActionResult Index()
{
    var x = db.People.Include("ServiceNeeded").ToList();
    return View(x);
}