实体框架

3
我正在进行MVC 3 Web应用程序并遇到了奇怪的问题。这里是一些代码:
模型声明:
public class Project
{
    public int ID { get; set; }

    [Required(ErrorMessage = "Write a title.")]
    public string Title { get; set; }

    public DateTime TimeAdded { get; set; }

    [Required(ErrorMessage = "Write some description.")]
    [MaxLength(int.MaxValue)]
    public string Content { get; set; }

    public ICollection<Comment> Comments { get; set; }
}   

public class Comment
{
    public int ID { get; set; }

    [Required()]
    public int ProjectID { get; set; }

    public DateTime TimeAdded { get; set; }

    [Required()]
    public string Text { get; set; }

    public Project project { get; set; }
}

控制器:
public class HomeController : Controller
{
    dataDBContext db = new dataDBContext();

    //
    // GET: /Home

    public ActionResult Index()
    {
        var comments = from c in db.Comments
                       select c;

        var projects = from p in db.Projects
                       orderby p.TimeAdded descending
                       select p;

        return View(projects.ToList());
    }
  1. When I run project Comments are not visible on my view.
  2. I'm setting a breakpoint just after both linq queries, debugging and checking "project" variable fields Comments, they are not populated. Then I'm checking "comments" variable, it has some data. Again checking "project" variable and SOMEHOW fields Comments are populated and finally Comments appears on website. If I won't set breakpoint and check if variable "comments" is populated they won't appear on website. (I hope this is understandable)
  3. I found simple workaround:

    public ActionResult Index()
    {
        var projects = from p in db.Projects
                       orderby p.TimeAdded descending
                       select p;
    
        foreach (var p in projects)
        {
            var comments = from c in db.Comments
                           where c.ProjectID == p.ID
                           select c;
    
    
            p.Comments = comments.ToList();
        }
    
        return View(projects.ToList());
    }
    

    but it looks (according to point 2) that this can be automatically populated SOMEHOW :)

有什么方法可以做到吗?
根据给定的答案,另一个尝试:
public class HomeController : Controller
{
    dataDBContext db;

    public HomeController()
    {
        db = new dataDBContext();
        db.Configuration.LazyLoadingEnabled = false;
    }

    //
    // GET: /Home

    public ActionResult Index()
    {
        var projects = from p in db.Projects
                       orderby p.TimeAdded descending
                       select p;

        return View(projects.ToList());
    }

我有一个外键。我添加了LazyLoadingEnabled。有一个project.ToList(),但它不起作用。
根据第二个答案,我做了这样的事情:
public class HomeController : Controller
{
    dataDBContext db;

    public HomeController()
    {
        db = new dataDBContext();
    }

    //
    // GET: /Home

    public ActionResult Index()
    {
        var projects = from p in db.Projects
                       orderby p.TimeAdded descending
                       select p;

        var comments = from c in db.Comments
                       select c;

        List<Comment> l = comments.ToList();

        return View(projects.ToList());
    }

我已经添加了 comments.ToList(),它可以工作。但我不确定这是否是正确的解决方案。可能比我的解决方法(步骤3)更好。有什么建议吗?
谢谢

1
你在第三个代码中写的纯属邪恶。希望你意识到了这一点。 - flq
1
你真的应该考虑关注点分离,你的控制器上承担了太多任务。创建一个包含返回数据方法的仓库并将其从控制器中移除。试着查看一些MVC最佳实践文档来帮助你朝正确的方向前进。 - Jason Yost
1
因为对于每个项目,您都要提取注释,这会为N个项目+1(即项目本身)提供N个选择语句。这相当低效,应该避免使用。 - flq
你解决了你的问题吗? - Nico
2个回答

5
如果在评论(Comments)和项目(Projects)之间存在外键关系,您可以像这样操作:
db.ContextOptions.LazyLoadingEnabled = false;
var projects = from p in db.Projects.Include("Comments")
                       orderby p.TimeAdded descending
                       select p;

当执行`.ToList()`时,它将加载所有项目的评论。您可以通过项目对象的导航属性“Comments”访问数据。请注意保留HTML标记。

我可能做错了什么,但它不起作用。我确定有外键。我添加了db.Confiburation.LazyLoadingEnabled = false。我对项目执行ToList(),但没有数据。 - A_lan
1
你在LINQ中设置了Include(“Comments”)吗?你在EDMX文件中导入外键了吗?你是否定义了从项目到评论的导航属性(在从数据库导入时的EDMX属性)? - Nico

0

当您在断点处停止并检查查询结果时,实际上会触发 "ToList" 执行,因此您的新代码正在执行与调试会话相同的自动填充。


我只是添加了“comments.ToList()”并且它可以工作。但我不确定这是否是正确的解决方案。 - A_lan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接