2013-08-21 24 views
0

我以前有下面的代码行从我AdminController已成功从一个疗程内恢复相关小节的列表中:填充IEnumberable <class>用JSON结果

[AcceptVerbs(HttpVerbs.Get)] 
public JsonResult GetCourseSections(int courseID) 
{ 
    var Sections = dbcontext.CourseSection.Where(cs => cs.CourseID.Equals(courseID)).Select(x => new 
    {    
    sectionID = x.CourseSectionID, 
    sectionTitle = x.Title 
); 
    return Json(Sections, JsonRequestBehavior.AllowGet); 
} 

笔者获悉借此出来的控制器,因为它是不好的做法调用dbcontext,所以我把它移到AdminViewModel。在我的AdminViewModel中,我有一个变量public List CourseSectionList {get;组; },我想用JSON请求细节填充这个变量。我的代码如下:

AdminViewModel

public void GetCourseSectionDetails(int courseID) 
{ 
    var Sections = dbcontext.CourseSection.Where(cs => cs.CourseID.Equals(courseID)).Select(x => new CourseSection 
    { 
    CourseSectionID = x.CourseSectionID, 
    Title = x.Title 
    }); 
    this.CourseSectionList = Sections.ToList(); 
} 

AdminController

[AcceptVerbs(HttpVerbs.Get)] 
public JsonResult GetCourseSections(int courseID) 
{ 
    avm.GetCourseSectionDetails(courseID); 
    var Sections = avm.CourseSectionList.Where(cs => cs.CourseID.Equals(courseID)).Select(x => new 
    {    
    sectionID = x.CourseSectionID, 
    sectionTitle = x.Title 
    }); 
    System.Diagnostics.EventLog.WriteEntry("Application", "JSON=" + Sections.ToList(), System.Diagnostics.EventLogEntryType.Error); 
    return Json(Sections, JsonRequestBehavior.AllowGet); 
} 

我收到错误实体或复杂类型 'MetaLearning.Data.CourseSection' 不能在LINQ to Entities查询中构造。如何使用节填充this.CourseSectionList变量?

回答

2

正如指出的您的错误信息,您不能在linq to entities中使用

.Select(m => new <Entity>{bla bla}) 

其中<Entity> ...是您模型的实体之一。

因此,无论您使用的是“非模式”类(DTO),其中有你需要的属性,或者你有选择之前枚举(因为linq to objects有没有这个限制)

.ToList() 
.Select(m => new <Entity>{bla bla}); 

你可以找到为什么这是不可能的一些很好的解释here

编辑:

你也可以做这样的事情,如果你想撷取您的实体只有一些特性,并且不想使用DTO:

return ctx 
     .CourseSection 
     .Where(cs => cs.CourseID.Equals(courseID)) 
     //use an anonymous object to retrieve only the wanted properties 
     .Select(x => new 
       { 
        c= x.CourseSectionID, 
        t= x.Title, 
       }) 
     //enumerate, good bye linq2entities 
     .ToList() 
     //welcome to linq2objects 
     .Select(m => new CourseSection { 
        CourseSectionID = m.c, 
        Title = m.t, 
      }) 
      .ToList(); 
0

您不需要在控制器中重复相同的代码,但直接将列表传递给视图。

这就是说我告诉你,在你的视图模型中放置数据访问代码比保存在控制器中更糟。我建议你具有特定DAL层:

public interface IRepository 
{ 
    public IList<CourseSection> GetSections(int courseID); 
} 

这将是实现:

public class RepositoryEF : IRepository 
{ 
    public IList<CourseSection> GetSections(int courseID) 
    { 
     using (ctx = new YourDbContextHere()) 
     { 
      return ctx 
       .CourseSection 
       .Where(cs => cs.CourseID.Equals(courseID)) 
       .Select(x => new CourseSection 
       { 
        CourseSectionID = x.CourseSectionID, 
        Title = x.Title, 
       }) 
       .ToList(); 
     } 
    } 
} 

终于有您的控制器带库的依赖:

public class SomeController : Controller 
{ 
    private readonly IRepository repo; 
    public SomeController(IRepository repo) 
    { 
     this.repo = repo; 
    } 

    [AcceptVerbs(HttpVerbs.Get)] 
    public ActionResult GetCourseSections(int courseID) 
    { 
     var sections = this.repo.GetSections(courseID); 
     return Json(sections, JsonRequestBehavior.AllowGet); 
    } 
} 
+0

我不认为解决他们虽然错误。 – asymptoticFault

+1

虽然好的重构建议。 – asymptoticFault

+1

但是你不能投影模型的实体... –

0

我这样做是使用Darin的答案为指导如下:

视图模型

public void GetCourseSectionDetails(int courseID) 
    { 
     this.CourseSectionList = dbcontext.CourseSection.AsEnumerable().Where(cs => cs.CourseID.Equals(courseID)).Select(x => new CourseSection 
     { 
      CourseSectionID = x.CourseSectionID, 
      Title = x.Title 
     }).ToList(); 
    } 

控制器

[AcceptVerbs(HttpVerbs.Get)] 
    public JsonResult GetCourseSections(int courseID) 
    {    
     var sections = avm.CourseSectionList; 
     return Json(sections, JsonRequestBehavior.AllowGet); 
    }