2010-06-14 12 views
7

staram się ASP.NET MVC 2 z Microsoft Entity Framework i gdy próbuję dodać nowe rekordy otrzymuję ten błąd:Mapowanie metadanych i informacji nie można znaleźć dla EntityType Exception

mapowanie i metadane informacje te nie mogą być znalezione dla EntityType „WebUI.Controllers.PersonViewModel”

My Entity Framework przechowuje rekordy kontenerów typu Osoba i moim zdaniem jest mocno wpisane w klasie PersonViewModel która wypływa z Osoba. Rekordy będą zapisywane poprawnie, dopóki nie spróbuję użyć pochodnej klasy widoku. Czy ktoś może wyjaśnić, dlaczego klasa metadanych nie działa, gdy wyprowadzam mój model widoku? Chcę mieć możliwość używania mocno wpisanego modelu, a także używać adnotacji danych (metadanych) bez konieczności mieszania logiki pamięci (klasy EF) i logiki prezentacji (widoków).

// Rest of the Person class is autogenerated by the EF 
[MetadataType(typeof(Person.Metadata))] 
public partial class Person 
{ 
    public sealed class Metadata 
    { 
    [DisplayName("First Name")] 
    [Required(ErrorMessage = "Field [First Name] is required")] 
    public object FirstName { get; set; } 

    [DisplayName("Middle Name")]    
    public object MiddleName { get; set; } 

    [DisplayName("Last Name")] 
    [Required(ErrorMessage = "Field [Last Name] is required")] 
    public object LastName { get; set; } 
    } 
} 

// From the View (PersonCreate.aspx) 
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" 
     Inherits="System.Web.Mvc.ViewPage<WebUI.Controllers.PersonViewModel>" %> 

// From PersonController.cs 
public class PersonViewModel : Person 
{ 
    public List<SelectListItem> TitleList { get; set; } 
} // end class PersonViewModel 

Aktualizacja: tutaj jest ślad stosu:

 
[InvalidOperationException: Mapping and metadata information could not be found for EntityType 'WebUI.Controllers.PersonViewModel'.] 

System.Data.Objects.ObjectContext.GetTypeUsage(Type entityCLRType) +11531168 

System.Data.Objects.ObjectContext.VerifyRootForAdd(Boolean doAttach, String entitySetName, IEntityWrapper wrappedEntity, EntityEntry existingEntry, EntitySet& entitySet, Boolean& isNoOperation) +195 

System.Data.Objects.ObjectContext.AddObject(String entitySetName, Object entity) +243 

DomainModel.Entities.MyEntities.AddToPeople(Person person) in C:\Users\...\Documents\Visual Studio 2010\Projects\PersonWeb\DomainModel\Entities\MyEntities.Designer.cs:71 

DomainModel.Concrete.Repository.SavePerson(Person person) in C:\Users\...\Documents\Visual Studio 2010\Projects\PersonWeb\DomainModel\Concrete\Repository.cs:42 

WebUI.Controllers.PersonController.Create(FormCollection form, Int32 hidCancel) in C:\Users\...\Documents\Visual Studio 2010\Projects\PersonWeb\WebUI\Controllers\PersonController.cs:163 
    lambda_method(Closure , ControllerBase , Object[]) +165 

System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +258 

System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext 
controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +39 

System.Web.Mvc.c__DisplayClassd.b__a() +125 

System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +640 

System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext 
controllerContext, IList1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +312 

System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +709 

System.Web.Mvc.Controller.ExecuteCore() +162 

System.Web.Mvc.c__DisplayClass8.b__4() +58 

System.Web.Mvc.Async.c__DisplayClass1.b__0() +20 

System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +453 

System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +371 

Odpowiedz

1

Właśnie miałem podobny problem (poszukiwanie wyjątkiem prowadzi mnie tutaj), z MVC3, która dla mnie okazało się, ponieważ przeniosłem mój plik edmx i nie wiedziałem, gdzie powinien wskazywać atrybut przestrzeni nazw EdmEntityTypeAttribute.

Tworzę strukturę podobną do tej, którą opisałeś, dzięki czemu miałem klasę modelu, która pochodzi od typu jednostki i ponownie otrzymałem ten sam błąd. Jeśli skopiuję EdmEntityTypeAttribute z typu jednostki do klasy pochodnej, problem zniknie (przynajmniej w przypadku pisania, pojawi się inny problem podczas czytania). Prowadzi mnie to do przekonania, że ​​framework prawdopodobnie używa odbicia, aby przesłuchać klasę przekazaną do metody add, aby określić, jakie atrybuty są obecne, ale tylko na faktycznym typie (drzewo dziedziczenia jest ignorowane).

Pomyślałem o tym i to ma sens, jeśli myślisz o danych wypływających z bazy danych. Gdybyś miał pobrać listę obiektów "Person", framework musiałby zdecydować, do której klasy tworzyć i zapełniać z tabeli, i nie wie o klasie pochodnej Modelu, więc będzie musiał utworzyć klasę podstawową . W najlepszym przypadku oznacza to, że wchodzisz w interakcję z pamięcią masową przy użyciu typów surowych jednostek do odczytu i typów modeli do pisania, co wydaje się być mylące.

Użycie klas częściowych w wygenerowanych typach encji pozwala na ich rozszerzenie, jeśli zachodzi taka potrzeba, lub jeśli chcesz jawnie oddzielić obiekt i typy modeli, wówczas może być wymagane mapowanie obiektów.

Oczywiście nadal poznaję strukturę podmiotu, więc może pojawić się inny sposób obejścia problemu. Zakładam, że już znalazłeś rozwiązanie, które działa dla Ciebie.

1

Dla mnie był to prosty problem polegający na tym, że przez przypadek nazwałem moją tabelę UserAccount w mojej bazie danych, gdy wartość w pliku * .edmx była UserAccounts. HTH.

Powiązane problemy