2013-04-17 28 views
5

Tôi có một viewmodel mà cần dữ liệu từ hai mô hình người và địa chỉ:MVC4 C# Populating dữ liệu trong một viewmodel từ cơ sở dữ liệu

Models:

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 là như vậy

public class PersonAddViewModel 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string Street { get; set; } 
} 

Tôi đã thử một số cách để lấy dữ liệu vào viewmodel và chuyển nó vào khung nhìn. Sẽ có nhiều bản ghi được trả lại để hiển thị.

phương pháp mới nhất của tôi là Populating mô hình điểm như vậy:

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

tôi nhận được một lỗi trên địa chỉ Địa chỉ = db ... dòng "EntityCommandExecutionException là unhandled bởi mã người dùng

thế nào. bạn có thể cư một mô hình quan điểm với nhiều hồ sơ và chuyển cho một cái nhìn

giải pháp cuối cùng:?

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); 
} 
.210
+0

là gì 'db' trong trường hợp này? Và thông điệp của ngoại lệ là gì? Bạn đang sử dụng Entity Framework hoặc LinqToSql? Bất cứ điều gì 'db' dường như gặp sự cố khi thực hiện lệnh để truy xuất dữ liệu nhưng không có thêm thông tin, nó có thể là bất cứ điều gì. –

+0

@Brian S Tôi đang sử dụng khung pháp nhân. db là ngữ cảnh. – Xaxum

+1

Tại sao bạn không sử dụng các thuộc tính điều hướng? – lahsrah

Trả lời

5

Lỗi đầu tiên, EntityCommandExecutionException cho biết n lỗi trong định nghĩa ngữ cảnh thực thể của bạn hoặc chính các thực thể. Điều này là ném một ngoại lệ bởi vì nó được tìm thấy cơ sở dữ liệu khác với cách bạn nói với nó rằng nó nên được. Bạn cần phải tìm ra vấn đề đó.

Thứ hai, về cách thích hợp để thực hiện việc này, mã bạn đã hiển thị sẽ hoạt động nếu ngữ cảnh của bạn được định cấu hình chính xác. Tuy nhiên, một cách tốt hơn là sử dụng các thuộc tính Navigational, miễn là bạn muốn lấy tất cả các bản ghi liên quan và không chỉ định các tham số mệnh đề Where khác. Một tài sản hàng hải có thể trông như thế này:

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

Sau đó, bạn chỉ cần nói:

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

Lưu ý: Nếu thiết lập để sử dụng bộ sưu tập, sử dụng '.FirstOrDefault()' sẽ chỉ cung cấp cho bạn địa chỉ đầu tiên trong bộ sưu tập - mặc dù tất cả chúng đều nằm trong bộ sưu tập. Nhưng vì mã OP có '.SingleOrDefault()', tôi cho rằng điều này đã được tính. '.FirstOrDefault()' cũng tốt hơn '.SingleOrDefault()', vì "single" là nhiều hơn cho khi bạn biết bạn sẽ chỉ nhận được một phản hồi. – vapcguy

+0

Xin lỗi thêm một lưu ý: Để có được điều này để làm việc cho tôi, tôi đã phải thêm '.Include (" Addresses ")' vào cuối 'db.Persons' trước khi bộ sưu tập sẽ điền vào. Tôi đã chỉnh sửa bài đăng để bao gồm bình luận về điều này và sửa lỗi nhiều cú pháp. – vapcguy

2

Để hiển thị danh sách các đối tượng, bạn có thể sử dụng một mô hình quan điểm chung mà có một danh sách chung:

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

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

Có một hành động điều khiển trở lại, nói tất cả mọi người từ cơ sở dữ liệu của bạn:

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

Sau đó, làm cho chế độ xem của bạn được nhập mạnh mẽ, sử dụng kiểu xem chung của bạn:

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

Cảm ơn bạn đã phản hồi. Tôi không chắc chắn làm thế nào điều này sẽ nhận được dữ liệu từ các dữ liệu mô hình địa chỉ là tốt? Tôi có thể nhận được những người hoặc địa chỉ mà không có một vấn đề nó chỉ là khi tôi cố gắng sử dụng một viewmodel để kết hợp chúng thành một mô hình vấn đề aries. – Xaxum

+0

Bạn nên tạo mối quan hệ giữa Người và Địa chỉ, nó sẽ phụ thuộc vào phạm vi ứng dụng của bạn, nhưng để đơn giản, hãy nói rằng đó là 1: 1 nghĩa là một Người có một Địa chỉ. Sau đó, bạn sẽ có thể truy cập địa chỉ của một người như person.Address.City, v.v. trong chế độ xem của bạn. Đây là liên kết đến các liên kết Code First http://weblogs.asp.net/manavi/archive/2011/01/23/associations-in-ef-code-first-ctp5-part-3-one-to-one- nước ngoài-key-hiệp hội.aspx – MattSull

+0

Đây có phải là những gì @sylon đã được đề cập ở trên là tài sản chuyển hướng? Tôi có mối quan hệ một đến nhiều, một người có thể có nhiều địa chỉ. Các khóa ngoại được thiết lập bởi khung thực thể nhưng có thể không có ảo tôi không thể tham chiếu như person.Adddress.City. – Xaxum

Các vấn đề liên quan