我有一个viewmodel,它需要来自两个模型人员和地址的数据:

楷模:

public class Person
{
   public int Id { get; set; }
   public string Name { get; set; }
   public int Age { get; set; }
   public int Gender { get; set; }
}

public class Address
{
   public int Id { get; set; }
   public string Street { get; set; }
   public int Zip { get; set; }
   public int PersonId {get; set; }
}

这样的Viewmodel就是这样
public class PersonAddViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Street { get; set; }
}

我尝试了几种方法将数据放入 View 模型并将其传递给 View 。将有多个记录返回显示。

我最新的方法是这样填充 View 模型:
private AppContexts db = new AppContexts();
public ActionResult ListPeople()
{
    var model = new PersonAddViewModel();
    var people = db.Persons;
    foreach(Person p in people)
    {
        Address address = db.Addresses.SingleOrDefault(a => a.PersonId == p.Id)
        model.Id = p.Id;
        model.Name = p.Name;
        model.Street = address.Street;
    }
    return View(model.ToList());
}

在用户代码未处理“EntityCommandExecutionException的地址地址= db ...”行时出现错误。

如何用多个记录填充 View 模型并传递给 View ?

最终解决方案:
private AppContexts db = new AppContexts();
private AppContexts dbt = new AppContexts();
public ActionResult ListPeople()
{
    List<PersonAddViewModel> list = new List<PersonAddViewModel>();
    var people = db.Persons;
    foreach(Person p in people)
    {
        PersonAddViewModel model = new PersonAddViewModel();
        Address address = dbt.Addresses.SingleOrDefault(a => a.PersonId == p.Id)
        model.Id = p.Id;
        model.Name = p.Name;
        model.Street = address.Street;
    }
    return View(list);
}

最佳答案

首先,EntityCommandExecutionException错误指示您的实体上下文或实体本身的定义错误。这引发了异常,因为它发现数据库与您告诉数据库的方式不同。您需要找出该问题。

其次,关于正确的方法,如果正确配置了上下文,那么您显示的代码应该可以正常工作。但是,一种更好的方法是使用导航属性,只要您要获取所有相关记录而不指定其他Where子句参数即可。导航属性可能如下所示:

public class Person
{
   public int Id { get; set; }
   public string Name { get; set; }
   public int Age { get; set; }
   public int Gender { get; set; }

   public virtual Address Address { get; set; }
   // or possibly, if you want more than one address per person
   public virtual ICollection<Address> Addresses { get; set; }
}

public class Address
{
   public int Id { get; set; }
   public string Street { get; set; }
   public int Zip { get; set; }
   public int PersonId { get; set; }

   public virtual Person Person { get; set; }
}

然后,您只需说:
public ActionResult ListPeople()
{
    var model = (from p in db.Persons // .Includes("Addresses") here?
                select new PersonAddViewModel() {
                    Id = p.Id,
                    Name = p.Name,
                    Street = p.Address.Street,
                    // or if collection
                    Street2 = p.Addresses.Select(a => a.Street).FirstOrDefault()
                });

    return View(model.ToList());
}

09-30 12:18
查看更多