Je suis un exemple très basique de code-first Entity Framework (version 4.1) dans ASP.NET MVC 4 (en utilisant l'exemple EBuy dans O'Reilly's Programming ASP.NET MVC 4). J'ai cherché des solutions à ce problème et jusqu'à présent, je n'ai rien trouvé. Le problème de base est ce code dans mon contrôleur :
public ActionResult Details(long id)
{
using (var db = new EbuyDataContext())
{
var rep = db.Auctions;
var auction = rep.Find(id);
return View(auction);
}
}
lance un ArgumentNullException La valeur ne peut pas être nulle. Nom du paramètre : key. quand il atteint l'appel rep.Find(id). Il est intéressant de noter que, lorsque l'on pénètre dans le code, la propriété db.Auctions contient le message "Expanding the Results View will enumerate the IEnumerable" et, si l'on clique dessus, les deux entités attendues qui viennent d'être extraites de la base de données apparaissent. Cependant, l'objet rep présente le message "Children could not be evaluated" lorsqu'il est inspecté.
Un code "Create" assez similaire comme celui-ci fonctionne bien :
[HttpPost]
public ActionResult Create(Auction auction)
{
var db = new EbuyDataContext();
db.Auctions.Add(auction);
db.SaveChanges();
return View(auction);
}
C'est mon contexte db :
namespace Ebuy.DataAccess
{
public class EbuyDataContext : DbContext
{
public DbSet<Auction> Auctions { get; set; }
}
}
et c'est ma classe modèle :
namespace Ebuy.DomainModel
{
public class Auction
{
public long Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public decimal StartPrice { get; set; }
public decimal CurrentPrice { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
}
}
J'ai trouvé une référence qui parlait du fait que les POCO et le dbcontext se trouvaient dans des espaces de noms ou des assemblages différents. Quelqu'un sait-il pourquoi le code Create fonctionne et pas le Find ?
Editar: La trace de la pile est :
L'exception System.ArgumentNullException n'a pas été gérée par le code utilisateur.
Message=Value ne peut pas être nulle. Nom du paramètre : key Source=mscorlib
ParamName=key StackTrace : at System.Collections.Generic.Dictionary2.FindEntry(TKey key) at System.Collections.Generic.Dictionary
2.ContainsKey(TKey key) at System.Data.Entity.Internal.InternalContext.TryUpdateEntitySetMappingsForType(Type entityType) at System.Data.Entity.Internal.InternalContext.IsEntityTypeMapped(Type entityType) at System.Data.Entity.Internal.Linq.InternalSet1.Find(Object[] keyValues) at System.Data.Entity.DbSet
1.Find(Object[] keyValues) at Ebuy.Website.Controllers.AuctionsController.Details(Int64 id) in C:\Users\John\Documents\Visual Studio 2010 \Projects\Ebuy.Website\Ebuy.Website\Controllers\AuctionsController.cs :ligne 26 at lambda_method(Closure , ControllerBase , Object[] ) at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary2 parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary
2 paramètres) at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c_. DisplayClass42.b _41() at System.Web.Mvc.Async.AsyncResultWrapper.<>c_. _DisplayClass81.<BeginSynchronous>b__7(IAsyncResult _) at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult
1.End() at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c _DisplayClass37.<>c\ DisplayClass39.b _33() at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c_. DisplayClass4f.b _49() InnerException :
Edit 2 : La table a bien la colonne Id comme clé primaire. Mise à jour : Sur la base du commentaire de nemesv, j'ai vérifié les versions. J'utilise .NET Framework v 4.0. L'application Web MVC, lors de sa création, a utilisé Nuget pour obtenir la version 5.0 de EF (bien que la référence réelle soit le runtime EF 4.0.30319 v4.4.0.0). J'ai ajouté le projet DataAccess et lui ai donné une référence à un fichier différents EF (runtime 4.0.30319 v4.1.0.0). J'ai changé la référence du projet DataAccess pour le même EF que l'application Web et maintenant j'obtiens une exception différente : InvalidOperationException Le contexte ne peut pas être utilisé pendant la création du modèle. Cela semble être un problème lors de l'utilisation de EF dans une application N-tier, je vais donc suivre ce fil de discussion et faire un rapport.
Fixe : J'ai lu quelques trucs sur les paramètres de LazyLoading dans EF et aussi sur la façon dont le chargement se fait quand on accède à une propriété d'une entité. Comme je n'accède pas vraiment à une propriété d'une entité avant d'essayer d'en trouver une et en pensant que peut-être LazyLoading est la valeur par défaut dans EF 5.0, j'ai ajouté un constructeur par défaut à ma classe EbuyDataContext comme suit :
public class EbuyDataContext : DbContext
{
public EbuyDataContext()
{
//Configuration.LazyLoadingEnabled = false;
}
public DbSet<Auction> Auctions { get; set; }
}
J'ai également réglé le paramètre LazyLoadingEnabled sur false, puis je l'ai exécuté et voilà ! Le succès est au rendez-vous ! Cependant, j'ai pensé que je devais revérifier cela, donc j'ai commenté le paramètre LazyLoadingEnabled, j'ai fait une reconstruction propre et cela fonctionnait toujours. J'ai commenté le constructeur par défaut et cela fonctionne toujours - est-ce que quelque chose d'autre a changé lorsque je l'ai exécuté avec le paramètre LazyLoadingEnabled en place ?