【问题标题】:linq to sql geting data from 2 tableslinq to sql 从 2 个表中获取数据
【发布时间】:2016-03-06 11:35:54
【问题描述】:

我正在尝试使用 Linq 从 2 个表中获取数据,其中一个表对第二个表有 FK,但没有必要有数据(表审查可能有每个审查 cmets(很多))我想要得到的是:在单个视图中获取所有评论,如果有任何 cmets 显示与评论​​ ID 相关的评论 尝试使用 join 在我的视图中出现错误(模型传递错误我尝试了每个表模型)这是我的代码:

     public ActionResult ttt()
    {
        var model = from rev in db.reviews
                    join com in db.Comments
                    on rev.ReviewId equals com.ReviewId into JoineRevCom
                    from com in JoineRevCom.DefaultIfEmpty()
                    select new
                    {
                        rev.ReviewBody,
                        rev.ReviewHeadLine,
                        Comments = com != null ? com.CommentBody : null
                    };
        return View(model);

    }
@model IEnumerable< SiteMvcPro.Models.Review>

【问题讨论】:

  • 您的select new { ... } 正在创建匿名对象的集合(不是Review 对象的集合)。您需要创建具有所需属性的视图模型(例如ReviewVM)并使用select new ReviewVM { .... }(并将视图中的模型更改为model IEnumerable&lt;ReviewVM&gt;
  • 查看以下网页的左外连接:code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b#content

标签: c# entity-framework linq-to-sql asp.net-mvc-5


【解决方案1】:

与往常一样,我会首先为此视图编写一个包含我想显示的信息的视图模型,并且从不向您的视图发送匿名对象,就像您在代码中所做的那样。

假设您要显示评论列表,并为每个评论显示相应 cmets 的列表。所以你的视图模型可能看起来像这样:

public class ReviewViewModel
{
    public int ReviewId { get; set; }
    public string ReviewBody { get; set; }
    public string ReviewHeadLine { get; set; }
    public IList<CommentViewModel> Comments { get; set; }
}

public class CommentViewModel
{
    public string CommentBody { get; set; }
}

有了这个定义,您可以执行 LINQ 查询来提取必要的数据并投影到这个视图模型:

IEnumerable<ReviewViewModel> viewModel = 
    from review in db.reviews
    join comment in db.Comments
    on review.ReviewId equals comment.ReviewId into joinedReviewComment
    select new ReviewViewModel // <-- Always project to a view model and never to an anonymous object
    {
        review.ReviewBody,
        review.ReviewHeadLine,
        Comments = joinedReviewComment.Select(c => new CommentViewModel
        {
            CommentBody = c.CommentBody,
        }).ToList(),
    };

return View(viewModel.ToList()); // <-- Always pass a view model to your view

现在剩下的就是在强类型视图中显示这些信息:

@model IList<ReviewViewModel>

<table>
    <thead>
        <tr>
            <th>Review id</th>
            <th>Review body</th>
            <th>Review headline</th>
            <th>Review comments</th>
        </tr>
    </thead>
    <tbody>
        @for (var i = 0; i < Model.Count; i++)
        {
            <tr>
                <td>@Html.DisplayFor(x => x[i].ReviewId)</td>
                <td>@Html.DisplayFor(x => x[i].ReviewBody)</td>
                <td>@Html.DisplayFor(x => x[i].ReviewHeadLine)</td>
                <td>
                    @for (var j = 0; j < Model[i].Comments.Count; j++)
                    {
                        <div>
                            @Html.DisplayFor(x => x[i].Comments[j].CommentBody)
                        </div>
                    }
                </td>
            </tr>
        }
    </tbody>
</table>

据说投影是一回事,但过滤数据是另一回事。假设您有数百万条评论,并且每条评论都有数百万条 cmets。进行上述查询只会使您的服务器很快关闭。因此,在设计应用程序和视图时请考虑这一点。不要犹豫,使用 Where、Skip 和 Take 运算符将您的结果集过滤成有意义的数据集合,这些数据集合足够合理,可以显示在单个视图上。

【讨论】:

    猜你喜欢
    • 2013-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-03
    • 1970-01-01
    • 2013-02-13
    相关资源
    最近更新 更多