使用JSON结果</class>填充IEnumerable <class>

时间:2013-08-21 16:15:41

标签: json linq entity-framework asp.net-mvc-4

我以前在我的AdminController中有以下代码行,它在一个课程中成功返回了相关小节的列表:

[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查询中构建。如何使用Sections填充this.CourseSectionList变量?< / p>

3 个答案:

答案 0 :(得分: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();

答案 1 :(得分: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);
    }
}

答案 2 :(得分: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);
    }