LINQ选择多个或语句返回distinct

时间:2015-08-17 13:12:06

标签: c# linq

我想在具有关键约束的多个数据集中搜索多个列。搜索功能本身有效,但在应用.Distinct()时,将返回错误,指出它无法找到类似的密钥。

    public async Task<ActionResult> SearchResults(string q)
    {

        var SearchResult = from Result in db.comments select Result;
        if (!String.IsNullOrEmpty(q))
        {
            var Found = SearchResult.Where(Result => Result.ticket.summary.ToUpper().Contains(q.ToUpper()) || Result.ticket.main_ticket.Contains(q) || Result.ticket.detailed_description.Contains(q.ToLower()) || Result.ticket.ticket.Contains(q) || Result.comment.Contains(q));
            if (Found== null)
            {
                return Content("No Data.");

            }
            else
            {
                ViewBag.SearchCount = Found.Count();

                return View(Found.ToList());
            }
        }
        else
        {
            return Content("404");
        }
      }

//数据库故障单

||------------------------||
|| ticket_id              ||
|| summary                ||
|| main_ticket            ||
|| detailed_description   ||
|| ticket                 ||
|| comment_id             ||
||------------------------||

//数据库评论

||---------------||
|| comment_id    ||
|| comment       ||
|| RowVerison    ||
||---------------||

当我搜索字母T时,我知道发生了什么事情它在comments.comment,tickets.summary和tickets.detail_description

中找到了字母T.

如何将返回的结果限制为不同的密钥对?

我应该根据返回的数据创建一个列表,然后比较列表并只显示Distinct吗?

或者我有一种更简单的方式吗?

[更新 - 找到解决方案] 如果我使用Model&而不是连接到.edmx SQLExpress服务器表的Controller,那么Andrei的答案就是解决方案。在使用我之前,我建议使用他的例子。

虽然Distinct无法导入Ajax库并使用DistinctBy Worked!

using Microsoft.Ajax.Utilities;

我将Where()行更改为此

var Found = SearchResult.Where(Result => Result.ticket.summary.ToUpper().Contains(q.ToUpper()) || Result.ticket.main_ticket.Contains(q) || Result.ticket.detailed_description.Contains(q.ToLower()) || Result.ticket.ticket.Contains(q) || Result.comment.Contains(q)).DistinctBy(Result => Result.ticket_id).ToList();

并从我的视图中删除了.ToList()。

return View(Found);

将返回正确数量的结果返回给我的ViewBag.SearchCount,并将正确的数据返回到我的Razor View

@model IEnumerable<TICKETS.Controllers.comments>

@{
    ViewBag.Title = @ViewBag.SearchCount+ " result(s) for: ";

}


<div class="row">

                    <div class="col-lg-8">
                        <div class="panel panel-color panel-info">
                            <div class="panel-heading"> 
                                <h3 class="panel-title">All Results - @ViewBag.SearchCount Result(s) found.</h3> 
                            </div> 
                            <div class="panel-body">
                                @foreach (var item in Model) {

                                    <h3>          
    <a data_modal="" href="@Url.Action("Details","TICKETS", new{ @id=item.ticket_id})" id="open_modal">@Html.DisplayFor(modelItem => item.tickets.summary)</a>
    </h3>  
    <p>@item.ticket_id :@Html.DisplayFor(modelItem => item.tickets.start_date) - @Html.DisplayFor(modelItem => item.tickets.end_date)</p>
    <p>@Html.DisplayFor(modelItem => item.tickets.detailed_description)</p>
    <hr />  
                                }

                            </div> 
                        </div>
                    </div>
    </div>

1 个答案:

答案 0 :(得分:4)

C#不知道如何比较您的Result实例。因此,您需要引入Result类实例的显式比较。

您需要实施IEqualityComparer<Result>界面并将此界面的实例传递到.Distinct(resultEqualityComparer)来电。

我们说我有一个班级用户:

class User
{
    public string Id { get; set; }
    public string Name { get; set; }
}

这就是我比较我的User类实例的方法:

class UserEqualityComparer : IEqualityComparer<User>
{
    public bool Equals(User user1, User user2)
    {
        return user1.Id == user2.Id;
    }

    public int GetHashCode(User user)
    {
        return user.Id;
    }
}

GetHashCode 是一个应为不同用户实例返回唯一int值的函数。 Id是理想的,如果你没有,你必须根据你的阶级属性开发自己的公式。

用法非常简单:

var users = new List<User>();

users.Add(new User { Id = 1, Name = "John" });
users.Add(new User { Id = 1, Name = "Lorem" });
users.Add(new User { Id = 2, Name = "Smith" });

users.Distinct(new UserEqualityComparer());

因此,具有名称Lorem的用户将被过滤掉。