abstracted lucene/search stuff into Portoa
This commit is contained in:
parent
866964a764
commit
d2894435a1
@ -1,19 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace VideoGameQuotes.Api.Search {
|
|
||||||
/// <summary>
|
|
||||||
/// Exposes an interface to search for quotes
|
|
||||||
/// </summary>
|
|
||||||
public interface IQuoteSearcher {
|
|
||||||
/// <summary>
|
|
||||||
/// Searches for quote based on the given search query
|
|
||||||
/// </summary>
|
|
||||||
IEnumerable<SearchResult> Search(string query);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// (Re)builds the search index
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="replaceOldIndex">Set to false to not overwrite the old index with a brand new one.</param>
|
|
||||||
void BuildIndex(bool replaceOldIndex = true);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
namespace VideoGameQuotes.Api.Search {
|
|
||||||
/// <summary>
|
|
||||||
/// Exposes an interface to build and update a search index
|
|
||||||
/// </summary>
|
|
||||||
public interface ISearchIndexBuilder<T> {
|
|
||||||
/// <summary>
|
|
||||||
/// (Re)builds the search index
|
|
||||||
/// </summary>
|
|
||||||
void BuildIndex();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Updates the index for the specified <paramref name="indexableObject"/>
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="indexableObject">The object that needs its index updated</param>
|
|
||||||
void UpdateIndex(T indexableObject);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
namespace VideoGameQuotes.Api.Search {
|
|
||||||
public interface ISearchIndexLocator {
|
|
||||||
string IndexDirectory { get; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SearchIndexLocator : ISearchIndexLocator {
|
|
||||||
private readonly string indexDirectory;
|
|
||||||
|
|
||||||
public SearchIndexLocator(string indexDirectory) {
|
|
||||||
this.indexDirectory = indexDirectory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string IndexDirectory { get { return indexDirectory; } }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
|
|
||||||
namespace VideoGameQuotes.Api.Search {
|
|
||||||
/// <summary>
|
|
||||||
/// Exposes an interface to perform a full-text search
|
|
||||||
/// </summary>
|
|
||||||
public interface ISearcher<T> {
|
|
||||||
/// <summary>
|
|
||||||
/// Searches for records based on the given search query
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="query">The search term(s) to search for</param>
|
|
||||||
/// <param name="maxResults">The maximum number of results to return (<c>0</c> is unlimited); the default is <c>10</c></param>
|
|
||||||
IEnumerable<SearchResult<T>> Search(string query, int maxResults = 10);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
using Lucene.Net.Documents;
|
|
||||||
using Lucene.Net.Index;
|
|
||||||
|
|
||||||
namespace VideoGameQuotes.Api.Search.Lucene {
|
|
||||||
public interface ILuceneDocumentHandler<T> {
|
|
||||||
Document BuildDocument(T source);
|
|
||||||
Term GetIdTerm(T source);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
using Lucene.Net.Index;
|
|
||||||
using Portoa.Logging;
|
|
||||||
using Portoa.Persistence;
|
|
||||||
using VideoGameQuotes.Api.Persistence;
|
|
||||||
|
|
||||||
namespace VideoGameQuotes.Api.Search.Lucene {
|
|
||||||
public class LuceneEntityIndexBuilder<T> : ISearchIndexBuilder<T> where T : Entity<T, int> {
|
|
||||||
private readonly ILogger logger;
|
|
||||||
private readonly IndexWriter indexWriter;
|
|
||||||
private readonly ISearchService<T> searchService;
|
|
||||||
private readonly ILuceneDocumentHandler<T> documentHandler;
|
|
||||||
|
|
||||||
public LuceneEntityIndexBuilder(IndexWriter indexWriter, ISearchService<T> searchService, ILuceneDocumentHandler<T> documentHandler, ILogger logger) {
|
|
||||||
this.indexWriter = indexWriter;
|
|
||||||
this.searchService = searchService;
|
|
||||||
this.documentHandler = documentHandler;
|
|
||||||
this.logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void BuildIndex() {
|
|
||||||
logger.Info("Building lucene index");
|
|
||||||
foreach (var quote in searchService.GetAllIndexableRecords()) {
|
|
||||||
indexWriter.AddDocument(documentHandler.BuildDocument(quote));
|
|
||||||
}
|
|
||||||
|
|
||||||
indexWriter.Optimize();
|
|
||||||
indexWriter.Commit();
|
|
||||||
logger.Info("Finished building lucene index");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateIndex(T entity) {
|
|
||||||
if (entity.IsTransient()) {
|
|
||||||
throw new SearchIndexException(string.Format("Cannot add a transient entity to the index ({0})", entity));
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Info(string.Format("Updating index for {0}", entity));
|
|
||||||
//delete current document, if it exists
|
|
||||||
indexWriter.DeleteDocuments(documentHandler.GetIdTerm(entity));
|
|
||||||
indexWriter.AddDocument(documentHandler.BuildDocument(entity));
|
|
||||||
|
|
||||||
indexWriter.Commit();
|
|
||||||
logger.Info(string.Format("Finished updating index for {0}", entity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,50 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Lucene.Net.QueryParsers;
|
|
||||||
using Lucene.Net.Search;
|
|
||||||
using Portoa.Persistence;
|
|
||||||
using VideoGameQuotes.Api.Persistence;
|
|
||||||
using Directory = Lucene.Net.Store.Directory;
|
|
||||||
|
|
||||||
namespace VideoGameQuotes.Api.Search.Lucene {
|
|
||||||
/// <summary>
|
|
||||||
/// <see cref="ISearcher{T}"/> implementation for entities based on <c>Lucene.NET</c>
|
|
||||||
/// </summary>
|
|
||||||
public class LuceneEntitySearcher<T> : ISearcher<T> where T : Entity<T, int> {
|
|
||||||
private readonly QueryParser queryParser;
|
|
||||||
private readonly Directory indexDirectory;
|
|
||||||
private readonly ISearchService<T> searchService;
|
|
||||||
|
|
||||||
public LuceneEntitySearcher(QueryParser queryParser, Directory indexDirectory, ISearchService<T> searchService) {
|
|
||||||
this.queryParser = queryParser;
|
|
||||||
this.indexDirectory = indexDirectory;
|
|
||||||
this.searchService = searchService;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<SearchResult<T>> Search(string searchString, int maxResults = 10) {
|
|
||||||
if (string.IsNullOrWhiteSpace(searchString)) {
|
|
||||||
return Enumerable.Empty<SearchResult<T>>();
|
|
||||||
}
|
|
||||||
if (maxResults < 0) {
|
|
||||||
throw new ArgumentOutOfRangeException("maxResults", maxResults, "Maximum number of results must be greater than or equal to zero");
|
|
||||||
}
|
|
||||||
if (maxResults == 0) {
|
|
||||||
maxResults = int.MaxValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var query = queryParser.Parse(QueryParser.Escape(searchString));
|
|
||||||
var searcher = new IndexSearcher(indexDirectory, true);
|
|
||||||
try {
|
|
||||||
var docs = searcher
|
|
||||||
.Search(query, maxResults)
|
|
||||||
.scoreDocs;
|
|
||||||
|
|
||||||
var quotes = searchService.FindByIds(docs.Select(doc => int.Parse(searcher.Doc(doc.doc).GetField("id").StringValue())));
|
|
||||||
return quotes.Zip(docs, (entity, doc) => new SearchResult<T> { Entity = entity, Score = doc.score }).ToArray();
|
|
||||||
} finally {
|
|
||||||
searcher.Close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Lucene.Net.Search;
|
|
||||||
|
|
||||||
namespace VideoGameQuotes.Api.Search.Lucene {
|
|
||||||
public static class LuceneExtensions {
|
|
||||||
public static IEnumerable<Hit> ToEnumerable(this Hits hits) {
|
|
||||||
var iterator = hits.Iterator();
|
|
||||||
while (iterator.MoveNext()) {
|
|
||||||
yield return (Hit)iterator.Current;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,62 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using Lucene.Net.Analysis;
|
|
||||||
using Lucene.Net.Analysis.Standard;
|
|
||||||
using Lucene.Net.Documents;
|
|
||||||
using Lucene.Net.Index;
|
|
||||||
using Lucene.Net.QueryParsers;
|
|
||||||
using Lucene.Net.Search;
|
|
||||||
using Portoa.Persistence;
|
|
||||||
|
|
||||||
namespace VideoGameQuotes.Api.Search.Lucene {
|
|
||||||
/// <summary>
|
|
||||||
/// <see cref="IQuoteSearcher"/> implementation based on <c>Lucene.NET</c>
|
|
||||||
/// </summary>
|
|
||||||
public class LuceneQuoteSearcher : IQuoteSearcher {
|
|
||||||
private readonly ISearchIndexLocator indexLocator;
|
|
||||||
private readonly IRepository<Quote> quoteRepository;
|
|
||||||
private readonly Analyzer analyzer = new StandardAnalyzer();
|
|
||||||
private readonly QueryParser queryParser;
|
|
||||||
|
|
||||||
public LuceneQuoteSearcher(ISearchIndexLocator indexLocator, IRepository<Quote> quoteRepository) {
|
|
||||||
this.indexLocator = indexLocator;
|
|
||||||
this.quoteRepository = quoteRepository;
|
|
||||||
queryParser = new QueryParser("text", analyzer);
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnitOfWork]
|
|
||||||
public IEnumerable<SearchResult> Search(string searchString) {
|
|
||||||
if (string.IsNullOrWhiteSpace(searchString)) {
|
|
||||||
return Enumerable.Empty<SearchResult>();
|
|
||||||
}
|
|
||||||
|
|
||||||
var query = queryParser.Parse(QueryParser.Escape(searchString));
|
|
||||||
var searcher = new IndexSearcher(indexLocator.IndexDirectory);
|
|
||||||
return searcher
|
|
||||||
.Search(query)
|
|
||||||
.ToEnumerable()
|
|
||||||
.Select(hit => new SearchResult {
|
|
||||||
Score = hit.GetScore(),
|
|
||||||
Quote = quoteRepository.FindById(int.Parse(hit.GetDocument().GetField("id").StringValue()))
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
[UnitOfWork]
|
|
||||||
public void BuildIndex(bool replaceOldIndex = true) {
|
|
||||||
var indexWriter = new IndexWriter(indexLocator.IndexDirectory, analyzer, replaceOldIndex);
|
|
||||||
foreach (var quote in quoteRepository.Records) {
|
|
||||||
indexWriter.AddDocument(CreateDocument(quote));
|
|
||||||
}
|
|
||||||
|
|
||||||
indexWriter.Optimize();
|
|
||||||
indexWriter.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Document CreateDocument(Quote quote) {
|
|
||||||
var document = new Document();
|
|
||||||
document.Add(new Field("id", quote.Id.ToString(), Field.Store.YES, Field.Index.NO));
|
|
||||||
document.Add(new Field("text", quote.Text, Field.Store.YES, Field.Index.TOKENIZED));
|
|
||||||
return document;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
using System;
|
|
||||||
|
|
||||||
namespace VideoGameQuotes.Api.Search {
|
|
||||||
/// <summary>
|
|
||||||
/// Raised when an error occurs while reading/writing a search index
|
|
||||||
/// </summary>
|
|
||||||
public class SearchIndexException : Exception {
|
|
||||||
public SearchIndexException(string message = null, Exception innerException = null) : base(message, innerException) { }
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
namespace VideoGameQuotes.Api.Search {
|
|
||||||
/// <summary>
|
|
||||||
/// Represents a search result
|
|
||||||
/// </summary>
|
|
||||||
public class SearchResult<T> {
|
|
||||||
/// <summary>
|
|
||||||
/// A value (between 0 and 1, the higher the better) representing how good
|
|
||||||
/// the match is between the search query and the value
|
|
||||||
/// </summary>
|
|
||||||
public double Score { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The matched quote
|
|
||||||
/// </summary>
|
|
||||||
public T Entity { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
@ -37,9 +37,6 @@
|
|||||||
<Reference Include="log4net">
|
<Reference Include="log4net">
|
||||||
<HintPath>..\..\Lib\log4net.dll</HintPath>
|
<HintPath>..\..\Lib\log4net.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="Lucene.Net">
|
|
||||||
<HintPath>..\..\Lib\Lucene.Net.dll</HintPath>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="MySql.Data">
|
<Reference Include="MySql.Data">
|
||||||
<HintPath>..\..\Lib\MySql.Data.dll</HintPath>
|
<HintPath>..\..\Lib\MySql.Data.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
@ -69,13 +66,6 @@
|
|||||||
<Compile Include="Category.cs" />
|
<Compile Include="Category.cs" />
|
||||||
<Compile Include="CriterionHandler.cs" />
|
<Compile Include="CriterionHandler.cs" />
|
||||||
<Compile Include="Game.cs" />
|
<Compile Include="Game.cs" />
|
||||||
<Compile Include="Persistence\SearchService.cs" />
|
|
||||||
<Compile Include="Search\ISearcher.cs" />
|
|
||||||
<Compile Include="Search\ISearchIndexBuilder.cs" />
|
|
||||||
<Compile Include="Search\ISearchIndexLocator.cs" />
|
|
||||||
<Compile Include="Search\Lucene\ILuceneDocumentHandler.cs" />
|
|
||||||
<Compile Include="Search\Lucene\LuceneEntityIndexBuilder.cs" />
|
|
||||||
<Compile Include="Search\Lucene\LuceneEntitySearcher.cs" />
|
|
||||||
<Compile Include="Persistence\IUserRepository.cs" />
|
<Compile Include="Persistence\IUserRepository.cs" />
|
||||||
<Compile Include="Persistence\UserService.cs" />
|
<Compile Include="Persistence\UserService.cs" />
|
||||||
<Compile Include="QuoteFlag.cs" />
|
<Compile Include="QuoteFlag.cs" />
|
||||||
@ -85,9 +75,6 @@
|
|||||||
<Compile Include="QuoteFlagType.cs" />
|
<Compile Include="QuoteFlagType.cs" />
|
||||||
<Compile Include="Region.cs" />
|
<Compile Include="Region.cs" />
|
||||||
<Compile Include="GamingSystem.cs" />
|
<Compile Include="GamingSystem.cs" />
|
||||||
<Compile Include="Search\Lucene\QuoteDocumentHandler.cs" />
|
|
||||||
<Compile Include="Search\SearchIndexException.cs" />
|
|
||||||
<Compile Include="Search\SearchResult.cs" />
|
|
||||||
<Compile Include="User.cs" />
|
<Compile Include="User.cs" />
|
||||||
<Compile Include="UserGroup.cs" />
|
<Compile Include="UserGroup.cs" />
|
||||||
<Compile Include="Vote.cs" />
|
<Compile Include="Vote.cs" />
|
||||||
|
@ -4,8 +4,8 @@ using System.Reflection;
|
|||||||
using Microsoft.Practices.Unity;
|
using Microsoft.Practices.Unity;
|
||||||
using Microsoft.Practices.Unity.InterceptionExtension;
|
using Microsoft.Practices.Unity.InterceptionExtension;
|
||||||
using Portoa.Persistence;
|
using Portoa.Persistence;
|
||||||
|
using Portoa.Search;
|
||||||
using VideoGameQuotes.Api;
|
using VideoGameQuotes.Api;
|
||||||
using VideoGameQuotes.Api.Search;
|
|
||||||
|
|
||||||
namespace VideoGameQuotes.Web.Configuration {
|
namespace VideoGameQuotes.Web.Configuration {
|
||||||
|
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Web.Mvc;
|
using System.Web.Mvc;
|
||||||
using Portoa.Persistence;
|
using Portoa.Persistence;
|
||||||
|
using Portoa.Search;
|
||||||
using Portoa.Validation.DataAnnotations;
|
using Portoa.Validation.DataAnnotations;
|
||||||
using Portoa.Web;
|
using Portoa.Web;
|
||||||
using Portoa.Web.Controllers;
|
using Portoa.Web.Controllers;
|
||||||
using Portoa.Web.Results;
|
using Portoa.Web.Results;
|
||||||
using VideoGameQuotes.Api;
|
using VideoGameQuotes.Api;
|
||||||
using VideoGameQuotes.Api.Search;
|
|
||||||
using VideoGameQuotes.Web.Models;
|
using VideoGameQuotes.Web.Models;
|
||||||
using VideoGameQuotes.Web.Security;
|
using VideoGameQuotes.Web.Security;
|
||||||
using VideoGameQuotes.Web.Services;
|
using VideoGameQuotes.Web.Services;
|
||||||
|
@ -13,7 +13,9 @@ using Lucene.Net.Util;
|
|||||||
using Microsoft.Practices.Unity;
|
using Microsoft.Practices.Unity;
|
||||||
using Microsoft.Practices.Unity.InterceptionExtension;
|
using Microsoft.Practices.Unity.InterceptionExtension;
|
||||||
using Portoa.Logging;
|
using Portoa.Logging;
|
||||||
|
using Portoa.Lucene;
|
||||||
using Portoa.Persistence;
|
using Portoa.Persistence;
|
||||||
|
using Portoa.Search;
|
||||||
using Portoa.Web;
|
using Portoa.Web;
|
||||||
using Portoa.Web.Models;
|
using Portoa.Web.Models;
|
||||||
using Portoa.Web.Security;
|
using Portoa.Web.Security;
|
||||||
@ -21,11 +23,10 @@ using Portoa.Web.Unity;
|
|||||||
using UnityGenerics;
|
using UnityGenerics;
|
||||||
using VideoGameQuotes.Api;
|
using VideoGameQuotes.Api;
|
||||||
using VideoGameQuotes.Api.Persistence;
|
using VideoGameQuotes.Api.Persistence;
|
||||||
using VideoGameQuotes.Api.Search;
|
|
||||||
using VideoGameQuotes.Api.Search.Lucene;
|
|
||||||
using VideoGameQuotes.Web.Configuration;
|
using VideoGameQuotes.Web.Configuration;
|
||||||
using VideoGameQuotes.Web.Controllers;
|
using VideoGameQuotes.Web.Controllers;
|
||||||
using VideoGameQuotes.Web.Models;
|
using VideoGameQuotes.Web.Models;
|
||||||
|
using VideoGameQuotes.Web.Search;
|
||||||
using VideoGameQuotes.Web.Security;
|
using VideoGameQuotes.Web.Security;
|
||||||
using VideoGameQuotes.Web.Services;
|
using VideoGameQuotes.Web.Services;
|
||||||
using Directory = Lucene.Net.Store.Directory;
|
using Directory = Lucene.Net.Store.Directory;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Portoa.Search;
|
||||||
using VideoGameQuotes.Api;
|
using VideoGameQuotes.Api;
|
||||||
using VideoGameQuotes.Api.Search;
|
|
||||||
|
|
||||||
namespace VideoGameQuotes.Web.Models {
|
namespace VideoGameQuotes.Web.Models {
|
||||||
public class SearchModel {
|
public class SearchModel {
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
using Lucene.Net.Documents;
|
using Lucene.Net.Documents;
|
||||||
using Lucene.Net.Index;
|
using Lucene.Net.Index;
|
||||||
|
using Portoa.Lucene;
|
||||||
|
using VideoGameQuotes.Api;
|
||||||
|
|
||||||
namespace VideoGameQuotes.Api.Search.Lucene {
|
namespace VideoGameQuotes.Web.Search {
|
||||||
public class QuoteDocumentHandler : ILuceneDocumentHandler<Quote> {
|
public class QuoteDocumentHandler : ILuceneDocumentHandler<Quote> {
|
||||||
|
|
||||||
public Document BuildDocument(Quote quote) {
|
public Document BuildDocument(Quote quote) {
|
||||||
var document = new Document();
|
var document = new Document();
|
||||||
document.Add(new Field("id", quote.Id.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
|
document.Add(new Field("id", quote.Id.ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED));
|
@ -1,13 +1,9 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Portoa.Persistence;
|
using Portoa.Persistence;
|
||||||
|
using Portoa.Search;
|
||||||
|
|
||||||
namespace VideoGameQuotes.Api.Persistence {
|
namespace VideoGameQuotes.Web.Search {
|
||||||
|
|
||||||
public interface ISearchService<T> where T : Entity<T, int> {
|
|
||||||
IEnumerable<T> FindByIds(IEnumerable<int> ids);
|
|
||||||
IEnumerable<T> GetAllIndexableRecords();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SearchService<T> : ISearchService<T> where T : Entity<T, int> {
|
public class SearchService<T> : ISearchService<T> where T : Entity<T, int> {
|
||||||
private readonly IRepository<T> repository;
|
private readonly IRepository<T> repository;
|
||||||
@ -18,7 +14,6 @@ namespace VideoGameQuotes.Api.Persistence {
|
|||||||
|
|
||||||
[UnitOfWork]
|
[UnitOfWork]
|
||||||
public IEnumerable<T> FindByIds(IEnumerable<int> ids) {
|
public IEnumerable<T> FindByIds(IEnumerable<int> ids) {
|
||||||
|
|
||||||
return repository
|
return repository
|
||||||
.Records
|
.Records
|
||||||
.Where(entity => ids.ToArray().Contains(entity.Id));
|
.Where(entity => ids.ToArray().Contains(entity.Id));
|
@ -49,6 +49,7 @@
|
|||||||
<Reference Include="Portoa.Log4Net">
|
<Reference Include="Portoa.Log4Net">
|
||||||
<HintPath>..\..\Lib\Portoa.Log4Net.dll</HintPath>
|
<HintPath>..\..\Lib\Portoa.Log4Net.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
|
<Reference Include="Portoa.Lucene, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL" />
|
||||||
<Reference Include="Portoa.NHibernate, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="Portoa.NHibernate, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<SpecificVersion>False</SpecificVersion>
|
<SpecificVersion>False</SpecificVersion>
|
||||||
<HintPath>..\..\Lib\Portoa.NHibernate.dll</HintPath>
|
<HintPath>..\..\Lib\Portoa.NHibernate.dll</HintPath>
|
||||||
@ -57,8 +58,6 @@
|
|||||||
<HintPath>..\..\Lib\Portoa.Web.dll</HintPath>
|
<HintPath>..\..\Lib\Portoa.Web.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="System.Data" />
|
|
||||||
<Reference Include="System.Drawing" />
|
|
||||||
<Reference Include="System.Web.DynamicData" />
|
<Reference Include="System.Web.DynamicData" />
|
||||||
<Reference Include="System.Web.Entity" />
|
<Reference Include="System.Web.Entity" />
|
||||||
<Reference Include="System.Web.ApplicationServices" />
|
<Reference Include="System.Web.ApplicationServices" />
|
||||||
@ -68,23 +67,15 @@
|
|||||||
<Reference Include="System.Core">
|
<Reference Include="System.Core">
|
||||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System.Data.DataSetExtensions">
|
|
||||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
|
<Reference Include="System.Web.Mvc, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
|
||||||
<Reference Include="System.Xml.Linq">
|
|
||||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="System.Web" />
|
<Reference Include="System.Web" />
|
||||||
<Reference Include="System.Web.Extensions">
|
<Reference Include="System.Web.Extensions">
|
||||||
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
<RequiredTargetFramework>3.5</RequiredTargetFramework>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System.Web.Abstractions" />
|
<Reference Include="System.Web.Abstractions" />
|
||||||
<Reference Include="System.Web.Routing" />
|
<Reference Include="System.Web.Routing" />
|
||||||
<Reference Include="System.Xml" />
|
|
||||||
<Reference Include="System.Configuration" />
|
<Reference Include="System.Configuration" />
|
||||||
<Reference Include="System.Web.Services" />
|
<Reference Include="System.Web.Services" />
|
||||||
<Reference Include="System.EnterpriseServices" />
|
|
||||||
<Reference Include="UnityGenerics">
|
<Reference Include="UnityGenerics">
|
||||||
<HintPath>..\..\Lib\UnityGenerics.dll</HintPath>
|
<HintPath>..\..\Lib\UnityGenerics.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
@ -101,6 +92,8 @@
|
|||||||
<Compile Include="Models\EditCategoryModel.cs" />
|
<Compile Include="Models\EditCategoryModel.cs" />
|
||||||
<Compile Include="Models\EditGameModel.cs" />
|
<Compile Include="Models\EditGameModel.cs" />
|
||||||
<Compile Include="Models\EditPublisherModel.cs" />
|
<Compile Include="Models\EditPublisherModel.cs" />
|
||||||
|
<Compile Include="Search\QuoteDocumentHandler.cs" />
|
||||||
|
<Compile Include="Search\SearchService.cs" />
|
||||||
<Compile Include="Services\CategoryService.cs" />
|
<Compile Include="Services\CategoryService.cs" />
|
||||||
<Compile Include="Services\GameService.cs" />
|
<Compile Include="Services\GameService.cs" />
|
||||||
<Compile Include="Services\PublisherService.cs" />
|
<Compile Include="Services\PublisherService.cs" />
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<%
|
<%
|
||||||
foreach (var result in Model.Results) {
|
foreach (var result in Model.Results) {
|
||||||
Html.RenderPartial("SingleQuote", new QuoteModel {Quote = result.Entity, User = Model.User });
|
Html.RenderPartial("SingleQuote", new QuoteModel { Quote = result.Record, User = Model.User });
|
||||||
}
|
}
|
||||||
%>
|
%>
|
||||||
</asp:Content>
|
</asp:Content>
|
Loading…
Reference in New Issue
Block a user