我正在使用围绕实体框架代码和ASP.NET MVC 5构建的N层解决方案。
我有以下的ActionResult在我的艺术家控制器。
public ActionResult Paintings(string urlfriendly)
{
var artist = _artistService.GetArtistByUrlFriendly(urlfriendly);
ArtistPaintingsVM vm = Mapper.Map<ArtistPaintingsVM>(artist);
return View(vm);
}这项服务最终会到达这里:
public Artist GetArtistByUrlFriendly(string urlFriendly)
{
var artist = _context.Artists.FirstOrDefault(a => a.UrlFriendly == urlFriendly && a.Verified);
if (artist != null)
{
artist.Paintings = _context.Paintings.Where(p => p.ArtistId == artist.Id && p.Verified).ToList();
}
return artist;
}当我跨过这段代码时,我得到了想要的结果。我得到了那名艺术家的两幅经过验证的画。然而,当我在没有调试的情况下运行应用程序时,我会得到艺术家的所有三幅画,即使其中一幅没有被验证!
我上面的代码应该只返回经过验证的绘画,并且它是在调试时返回的,而不是在正常运行模式下返回的。
以下是数据种子代码:
public class DXIntializer : DropCreateDatabaseAlways<DXContext>
{
protected override void Seed(DXContext context)
{
try
{
var artists = new List<Artist>
{
new Artist { FName = "Salvador", LName = "Dali", ImgURL = "http://i62.tinypic.com/ss8txxn.jpg", UrlFriendly = "salvador-dali", Verified = true }
};
artists.ForEach(a => context.Artists.Add(a));
context.SaveChanges();
var paintings = new List<Painting>
{
new Painting { Title = "The Persistence of Memory", ImgUrl = "http://i62.tinypic.com/xx8tssn.jpg", ArtistId = 1, Verified = true },
new Painting { Title = "Swans Reflecting Elephants", ImgUrl = "http://i62.tinypic.com/aa9tssn.jpg", ArtistId = 1, Verified = true },
new Painting { Title = "Crucifiction", ImgUrl = "http://i62.tinypic.com/qq0tssn.jpg", ArtistId = 1, Verified = false }
};
paintings.ForEach(p => context.paintings.Add(p));
context.SaveChanges();
}
catch (DbEntityValidationException ex)
{
foreach (var validationErrors in ex.EntityValidationErrors)
{
foreach (var validationError in validationErrors.ValidationErrors)
{
Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
}
}
}
}
}我做错了什么?
发布于 2015-02-27 12:16:37
你不应该把艺术家的财产设置成那样。因为这是EF导航属性。调试时,一旦代码到达服务(因为调试器读取属性),它就被加载,然后被linq语句的值覆盖。在没有调试的情况下运行时,更有可能的情况是,该属性实际上首先在映射器中读取(延迟加载),并且执行的查询是由EF定义的查询。
如果你只在一个地方需要它,你应该只写一次
artist.Paintings.Where(p => p.Verified)如果您在多个地方申购它,您可以为它创建一个属性。一个正确的方法是为你的艺术家定义一个额外的属性。
ICollection<Painting> VerifiedPaintings
{
get
{
return this.Paintings.Where(p => p.Verified);
}
}当您希望您的服务重新还原一个完全加载的对象时(例如,在您离开服务时释放您的DbContext时)。您应该将其加载到单独的列表中。
return new artistDto
{
Artist = artist ,
VerifiedPaintings = artist.Paintings.Where(p => p.Verified)
}https://stackoverflow.com/questions/28562549
复制相似问题