【问题标题】:MVC4 C# Populating data in a viewmodel from databaseMVC4 C#从数据库中填充视图模型中的数据
【发布时间】:2013-04-10 21:26:56
【问题描述】:

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

型号:

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; }
}

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

我的最新方法是这样填充视图模型:

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());
}

我在 Address address = db... 行出现错误“EntityCommandExecutionException is unhandled by user code。

如何使用多条记录填充视图模型并将其传递给视图?

最终解决方案:

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);
}

【问题讨论】:

  • 在这种情况下db 是什么?异常的信息是什么?您使用的是实体框架还是 LinqToSql?无论db 是什么似乎都无法执行命令来检索数据,但如果没有更多信息,它可能是任何东西。
  • @Brian S 我正在使用实体框架。 db 是上下文。
  • 你为什么不使用导航属性?
  • @sylon 我不太清楚导航属性是什么意思?我查了一下,发现在我的地址模型中的公共虚拟人员人员中会是这样的吗?
  • @Xaxum 给我们提供异常的详细信息?

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


【解决方案1】:

首先,EntityCommandExecutionException 错误表明您的实体上下文或实体本身的定义存在错误。这会引发异常,因为它发现数据库与您告诉它的方式不同。你需要弄清楚这个问题。

其次,关于执行此操作的正确方法,如果您的上下文配置正确,您显示的代码应该可以工作。但是,更好的方法是使用 Navigational 属性,只要您想要获取所有相关记录并且不指定其他 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());
}

【讨论】:

  • 注意:如果将其设置为使用集合,使用 .FirstOrDefault() 将只为您提供集合中的第一个地址 - 即使所有地址都在集合中。但是由于 OP 的代码有.SingleOrDefault(),我想这已经被考虑到了。 .FirstOrDefault() 也比 .SingleOrDefault() 好,因为当你知道你只会得到一个回应时,“single”更适合。
  • 对不起,还有一个注意事项:为了让这个对我有用,我必须在 db.Persons 的末尾添加 .Include("Addresses") 才能填充集合。我编辑了帖子以包含评论关于这一点并纠正了许多语法错误。
【解决方案2】:

为了显示对象列表,您可以使用具有通用列表的通用视图模型:

public class GenericViewModel<T>
{
    public List<T> Results { get; set; }

    public GenericViewModel()
    {
        this.Results = new List<T>();
    }
}

有一个返回的控制器动作,比如说你数据库中的所有人:

[HttpGet]
public ActionResult GetAllPeople(GenericViewModel<People> viewModel)
{
    var query = (from x in db.People select x); // Select all people
    viewModel.Results = query.ToList();

    return View("_MyView", viewModel);
}

然后将您的视图设为强类型,并采用您的通用视图模型:

@model NameSpace.ViewModels.GenericViewModel<NameSpace.Models.People>

【讨论】:

  • 感谢您的回复。我不确定这也将如何从地址模型数据中获取数据?我可以毫无问题地获取人员或地址,只是当我尝试使用视图模型将它们组合成一个模型时才会出现问题。
  • 您应该在 Person 和 Address 之间创建关系,这取决于您的应用程序的范围,但为简单起见,我们假设它是 1:1,即一个人有一个地址。然后,您将能够在您的视图中访问一个人的地址,例如 person.Address.City 等。这是 Code First 关联的链接weblogs.asp.net/manavi/archive/2011/01/23/…
  • 这是@sylon 上面提到的导航属性吗?我有一对多的关系,一个人可以有多个地址。外键是由实体框架设置的,但可能没有虚拟我无法像 person.Address.City 一样引用。
  • 是的,您需要按照@sylons 答案中的说明指定导航属性。
  • 感谢您的选择。这帮助我到达了我必须去的地方。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-15
相关资源
最近更新 更多