2011-11-09 52 views
0

我有一个MVC 3应用程序运行在MS SQL 2008数据库上,名为Documents的表。文档按数据库中的段落分解。 Documents表具有包含每个段落文本的DocText列,包含文档标题的DocTitle列。我的MVC 3应用程序具有搜索功能,可以在DocText列或DocTitle列中搜索单词或短语。一切工作正常,除非如果一个特定的文档的搜索词出现在多个段落中,我的列表返回该文档的多个实例。例如,如果用户搜索单词“预算”并且其中一个文档具有四个不同段落中的单词“预算”,则我的返回列表将该文档列出四次。基于不同的列或字段值筛选结果

我想要实现的是列出每个文档,包含搜索到的单词。无论搜索词出现在文档中的次数是多少,我只想按标题一次列出文档。唯一真正唯一的列是RecordID列,一个主键。

我的控制器:

public class SearchController : Controller 
{ 

    private GUICEEntities4 db = new GUICEEntities4(); 

    // 
    // GET: /Search/ 

    public ActionResult Index(string Keyword) 
    { 
     #region Keyword Search 
     if (!String.IsNullOrEmpty(Keyword)) { 
      var SearchDoc = db.Documents.Where(r => r.DocText.ToUpper().Contains(Keyword.ToUpper()) || r.Title.ToUpper().Contains(Keyword.ToUpper()) || r.DocNum.ToUpper().Contains(Keyword.ToUpper())); 

      ViewBag.CurrentKeyword = String.IsNullOrEmpty(Keyword) ? "" : Keyword; 

      return View(SearchDoc.ToList()); 
     } 
      else{ 
      return View(); 
      } 
       #endregion 
    } 

} 

我查看有以下几点:我如何能实现我的目标

@foreach (var item in Model) { 

    <tr> 
     <td> 
      <strong>AFI @Html.DisplayFor(modelItem => item.DocNum): @Html.DisplayFor(modelItem => item.Title)</strong> 
      <br /> 
      @Html.DisplayFor(modelItem => item.DocSummary) 
      <br /> 
      <span class="complianceitems">Number of compliance items:</span> (TBD) 
     </td> 

     <td> 
      <a href="/Documents/Index/@(Html.DisplayFor(modelItem => item.DocNum))">Checklist 
       Generator</a><br /> 
      <a href="/UploadedDocs/@Html.DisplayFor(modelItem => item.DocFileName)" target="_blank"> 
       Download PDF</a> 
     </td> 

有什么建议?

ADDED:每个文档都可以通过DocNum列标识,该列具有该特定文档的唯一文档编号。我尝试遍历列表来取出每个unqiue DocNum,然后尝试使DocNum不再出现在循环中...但我没有成功。

以下SQL语句为我提供了我需要的结果。该声明假设搜索词是“预算”。我不知道如何使用EF获得相同的结果。有什么建议么?

SELECT DISTINCT DocNum, Title FROM Documents 
WHERE 
DocText LIKE '%budget%' 
OR 
Documents.Title LIKE '%budget%' 
OR 
DocNum LIKE '%budget%' 

回答

0

这里的问题是在你的EF查询中,而不是与MVC有关的任何东西。自从我积极地使用EF之后已经有一段时间了,但最简单的方法可能是首先返回RecordIds。

var recordIds= db.Documents 
        .Where(r => 
         r.DocText.ToUpper().Contains(Keyword.ToUpper()) || 
         r.Title.ToUpper().Contains(Keyword.ToUpper()) || 
         r.DocNum.ToUpper().Contains(Keyword.ToUpper())) 
        .Select(d => d.RecordId) 
        .Distinct(); 

我不完全相信你会从那么每个单独的记录上做什么,因为没有在你的问题的足够信息。但这应该有所帮助。

更新:

var foundDocs = new List<YourType>(); 
recordIds.ToList().ForEach(r => foundDocs.Add(db.TblDocLists.Single(l => l.TheDocNum == r))); 
//I must point out that I'm not familiar with the latest versions of EF so this might be overkill. 
+0

这让我更接近。我使用了你的代码,但是把RecordID改为DocNum,这会给我找到搜索词的每个文档的文档编号。 – drjackevan

+0

我已经修正了我的问题,以根据您的建议显示我所做的更改。 – drjackevan

+0

这里的问题是'SearchDoc'是'IQueryable <>'和EF不支持拉这些记录。 – Buildstarted