所以我有这笔交易
模型
public class News
{
public News()
{
this.Created = DateTime.Now;
}
public int Id { get; set; }
public string Title { get; set; }
public string Preamble { get; set; }
public string Body { get; set; }
public DateTime Created { get; set; }
public int UserId { get; set; }
public virtual User User { get; set; }
public int CategoryId { get; set; }
public int ImageId { get; set; }
public virtual Image Image { get; set; }
public virtual Category Category { get; set; }
}
public class Image
{
public int Id { get; set; }
public string Name { get; set; }
public string ImageUrl { get; set; }
public Byte[] ImageData { get; set; }
public string ImageMimeType { get; set; }
}
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
}
....以下模型(这些模型连接到EfDbContext)连接到以下存储库......
接口/存储库
public class NewsRepository : INewsRepository
{
EfDbContext context = new EfDbContext();
public IQueryable<News> All
{
get { return context.News; }
}
public IQueryable<News> AllIncluding(params Expression<Func<News, object>>[] includeProperties)
{
IQueryable<News> query = context.News;
foreach (var includeProperty in includeProperties) {
query = query.Include(includeProperty);
}
return query;
}
public News Find(int id)
{
return context.News.Find(id);
}
public void InsertOrUpdate(News news)
{
if (news.Id == default(int)) {
// New entity
context.News.Add(news);
} else {
// Existing entity
context.Entry(news).State = EntityState.Modified;
}
}
public void Delete(int id)
{
var news = context.News.Find(id);
context.News.Remove(news);
}
public void Save()
{
context.SaveChanges();
}
}
public interface INewsRepository
{
IQueryable<News> All { get; }
IQueryable<News> AllIncluding(params Expression<Func<News, object>>[] includeProperties);
News Find(int id);
void InsertOrUpdate(News news);
void Delete(int id);
void Save();
}
在我的HomeController()中,我得到了一个JsonResult metod,我想返回上下文。 这是方法
Json请求
[HttpGet]
public JsonResult GetNews()
{
var p = newsRepository.AllIncluding(news => news.Category, news => news.Image);
return Json(p, JsonRequestBehavior.AllowGet);
}
我收到以下错误:
序列化“System.Data.Entity.DynamicProxies.News_96C0B16EC4AC46070505EEC7537EF3C68EE6CE5FC3C7D8EBB793B2CF9BD391B3”类型的对象时检测到循环引用。
我猜这与懒加载的东西有关(Iam目前正在学习C#)我发现这篇关于这个的文章......
http://hellowebapps.com/2010-09-26/producing-json-from-entity-framework-4-0-generated-classes/
但是我没有让它工作......我能读到的关于代码的是他们试图通过对象进行深度搜索......比我想不到的更多。
我的问题是如何传递lazyLoading对象?进入json / serializer 或者它不存在,对我如何进行的任何想法?
答案 0 :(得分:12)
由于Json是基于树的序列化格式,因此它与A-> B-> A的引用有问题。
我在某处读过您可以在视图模型中使用ScriptIgnore属性来防止此错误。但还没有测试过。
您可以将代码更改为以下(使用匿名类型)以成功检索项目:
var p = newsRepository.AllIncluding(news => news.Category, news => news.Image)
.Select(n => new {id = n.Id, Body = n.Body});
包含您希望在上一个Select
方法中显示的任何其他媒体资源。这使得您的Json结果也更加轻量级。
答案 1 :(得分:6)
添加到Kamyar的答案......
只有在使用MVC脚手架时,AllIncluding方法才可用。请参阅以下链接以获取该方法的列表: Mvc 3 Scaffolding: the Model passed to the View throws SQL errror
我尝试使用它,但仍然遇到循环引用错误,因为根对象仍然作为代理返回。所以我定制了方法来暂时关闭EF上下文中的ProxyCreationEnabled标志,并急切地加载方法参数中列出的指定属性。有关详细信息,请参阅以下链接: Loading from database without proxy classes?
为了使其工作,必须在设置仍处于关闭状态时执行查询,因此我必须调用查询的ToList()方法来执行查询,然后返回IEnumerable而不是IQueryable。这对我来说很有意义。
这是我使用的方法(“_context”是我的EF上下文的变量名称):
public IEnumerable<TEntity> ListIncluding<TEntity>(params Expression<Func<TEntity, object>>[] includeProperties)
where TEntity : class
{
bool cachedSetting = _context.Configuration.ProxyCreationEnabled;
_context.Configuration.ProxyCreationEnabled = false;
IQueryable<TEntity> query = _context.Set<TEntity>();
foreach (var includeProperty in includeProperties)
{
query = query.Include(includeProperty);
}
IEnumerable<TEntity> list = query.ToList();
_context.Configuration.ProxyCreationEnabled = cachedSetting;
return list;
}
然后可以使用以下语法调用它:
IEnumerable<News> newsItems = newsRepository.ListIncluding<News>(news => news.Category, news => news.Image);