2013-04-17 18 views
5

Mam ViewModel który potrzebuje danych z dwóch modeli osobowe i adres:MVC4 C# Wypełnianie danych w viewmodel z bazy

modele:

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 jako taki

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

Próbowałem kilka sposobów, aby uzyskać dane do viewmodel i przekazać go do widoku. Zostanie wyświetlonych wiele rekordów.

Moja najnowsza metoda wypełniania widoku modelu jako takie:

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

otrzymuję komunikat o błędzie na adres address = db ... linia „EntityCommandExecutionException był nieobsługiwany przez kod użytkownika

Jak. można wypełnić model widok z wielu rekordów i przejść do widoku

ostateczne rozwiązanie:

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

Co jest 'db' w tym przypadku? A jakie jest przesłanie wyjątku? Czy korzystasz z Entity Framework lub LinqToSql? Bez względu na to, że 'db' ma problemy z wykonywaniem komendy pobierania danych, ale bez dodatkowych informacji, może to być cokolwiek. –

+0

@ Brian S Używam framework entity. db jest kontekstem. – Xaxum

+1

Dlaczego nie korzystasz z właściwości nawigacji? – lahsrah

Odpowiedz

5

Po pierwsze, błędy wyjątku EntityCommandExecutionException wskazują n błąd w definicji kontekstu twojego podmiotu lub samych podmiotów. Jest to wyjątek, ponieważ okazało się, że baza danych różni się od sposobu, w jaki powiedziałeś, że powinna być. Musisz wymyślić ten problem.

Po drugie, jeśli chodzi o właściwy sposób wykonania tego, wyświetlony kod powinien działać, jeśli kontekst został poprawnie skonfigurowany. Ale lepszym sposobem byłoby użycie właściwości nawigacyjnych, o ile chcesz uzyskać wszystkie powiązane rekordy i nie określaj innych parametrów klauzuli Where. Właściwość nawigacyjny może wyglądać następująco:

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

Wtedy po prostu powiedzieć:

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

Uwaga: Jeśli ustawisz to, aby użyć kolekcji, użycie '.FirstOrDefault()' da ci tylko pierwszy adres w kolekcji - nawet jeśli wszystkie będą w kolekcji. Ale ponieważ kod OP miał '.SingleOrDefault()', przypuszczam, że to już było uwzględnione. '.FirstOrDefault()' jest również lepszy niż '.SingleOrDefault()', ponieważ "pojedynczy" jest bardziej przydatny, gdy wiesz, że dostaniesz tylko jedną odpowiedź. – vapcguy

+0

Przepraszam jeszcze jedną notatkę: Aby to działało, musiałem dodać '.Include (" Adresy ")' na końcu 'db.Persons' zanim kolekcja się wypełni. Edytowałem post, aby dołączyć komentarz na ten temat i korekta wielu błędów składniowych. – vapcguy

2

Do wyświetlania listy obiektów, można użyć rodzajowe widoku modelu, który ma listę Generic:

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

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

mają działanie kontrolera, która zwraca mówią wszyscy ludzie z bazy danych:

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

Następnie zdecydowanie zmodyfikuj widok, przyjmując ogólny model widoku:

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

Dzięki za odpowiedź. Nie jestem pewien, w jaki sposób pozyskałoby to dane z danych modelu adresu? Mogę dostać ludzi lub adres bez problemu, to jest właśnie wtedy, gdy próbuję użyć viewmodel, aby połączyć je w jeden model problemu. – Xaxum

+0

Powinieneś utworzyć relację między osobą i adresem, będzie to zależało od zakresu twojej aplikacji, ale dla uproszczenia załóżmy, że jest to 1: 1, tj. Jedna osoba ma jeden adres. Wtedy będziesz mieć dostęp do adresu osoby, np. Person.Address.City itp. W twoim widoku. Oto link do stowarzyszeń Code First http://weblogs.asp.net/manavi/archive/2011/01/23/associations-in-ef-code-first-ctp5-part-3-one-to-one- foreign-key-association.aspx – MattSull

+0

Czy to, co @sylon wspomniało powyżej, to właściwości nawigacyjne? Mam jedno do wielu relacji, jedna osoba może mieć wiele adresów. Klucze obce zostały utworzone przez strukturę encji, ale może bez wirtualnego nie mogę odwoływać się do osoby .Adddress.City. – Xaxum

Powiązane problemy