2013-08-21 26 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); 
    }