1

我目前正在.NET MVC 4 中构建一个网站,使用实体框架来访问 SQL Server。

网站应该有一个复杂的搜索,为用户提供多种选择,创建一个新的搜索(免费搜索),从最后 5 个搜索中选择(历史搜索),从存储的搜索参数中选择。

我遇到的问题是保存搜索参数/sql 字符串的概念,因为它不是基于会话/缓存的,应该存储在某个地方(SQL Server / MongoDB / XML)我很难获得最多优化路径,如果是 SQL 方式,则可以创建一个实体,将搜索参数存储为实体,然后将其转换为 SQL 字符串以进行搜索,或者将其存储在 XML 中,然后使用 JSON 对其进行序列化。

搜索的某些字段不是精确的数据库/实体匹配,需要求和/转换(例如将计算到特定时间的小时数)。

我更倾向于为此目的发挥 Entity Framework 的最佳能力。

如果可能,想听听专家的意见,谢谢。

4

3 回答 3

5

不确定这是否是“最优化”的路径,但认为实现起来似乎很简单:

//POCO class of item you want to search from database
public class SearchableItem
{
    public string Name { get; set; }
    public int Age { get; set; }
}

//MVC View Model for search page
public class SearchParamaters
{
    public int? MinAge { get; set; }
    public int? MaxAge { get; set; }
}

//Storable version for database
public class SavedSearchParameters : SearchParamters
{
    public int SavedSearchParametersId { get; set; }
}

//Use SearchParameters from MVC, or SavedSearchParamaters from EF
public IQueryable<SearchableItem> DoSearch(SearchParamaters sp)
{
    IQueryable<SearchableItem> query = db.SearchableItems;

    if (sp.MinAge.HasValue) query = query.Where(x => x.Age >= sp.MinAge.Value);
    if (sp.MaxAge.HasValue) query = query.Where(x => x.Age <= sp.MaxAge.Value);

    return query;
}

您还可以将SearchParameters类序列化为 XML/JSON 并将其保存在任何位置,然后将其反序列化并照常将其传递给DoSearch方法,这样您就不必每次想要添加搜索参数时都更改数据库架构


编辑:使用序列化的完整示例

\域\Person.cs

namespace YourApp.Domain
{
    public class Person
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }
}

\域\SavedPersonSearch.cs

namespace YourApp.Domain
{
    //Entity object with serialized PersonSearchParameters
    public class SavedPersonSearch
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Parameters { get; set; }
    }
}

\Models\PersonSearchParameters.cs

namespace YourApp.Models
{
    //MVC View Model for search page
    public class PersonSearchParameters
    {
        public int? MinAge { get; set; }
        public int? MaxAge { get; set; }
    }
}

\Helpers\SearchProvider.cs

using YourApp.Domain;
using YourApp.Models;

namespace YourApp.Helpers
{
    public class SearchProvider
    {
        private YourAppDbContext _context;

        public SearchProvider(YourAppDbContext context)
        {
            //This example uses the DbContext directly
            //but you could use a Unit of Work, repository, or whatever
            //design pattern you've decided on
            _context = context;
        }

        public IQueryable<Person> SearchPersons(int savedPersonSearchId)
        {
            var savedSearch = _context.SavedPersonSearches.Find(savedPersonSearchId);

            //deserialize (example assumes Newtonsoft.Json)
            var searchParams = JsonConvert.Deserialize<PersonSearchParameters>(savedSearch.Parameters);

            return SearchPersons(searchParams);
        }

        public IQueryable<Person> SearchPersons(PersonSearchParameters sp)
        {
            IQueryable<Person> query = _context.Persons;

            if (sp.MinAge.HasValue) query = query.Where(x => x.Age >= sp.MinAge.Value);
            if (sp.MaxAge.HasValue) query = query.Where(x => x.Age <= sp.MaxAge.Value);

            return query;
        }

        public void SavePersonSearch(PersonSearchParameters sp, string name)
        {
            var savedSearch = new SavedPersonSearch { Name = name };
            savedSearch.Parameters = JsonConvert.Serialize(sp);

            _context.SavedPersonSearches.Add(savedSearch);
            _context.SaveChanges();
        }
    }
}

\控制器\PersonController.cs

namespace YourApp.Controllers
{
    public class PersonsController : Controller
    {
        private SearchProvider _provider;
        private YourAppDbContext _context;

        public PersonsController()
        {
            _context = new YourAppDbContext();
            _provider = new SearchProvider(_context);
        }

        //Manual search using form
        // GET: /Persons/Search?minAge=25&maxAge=30
        public ActionResult Search(PersonSearchParameters sp)
        {
            var results = _provider.SearchPersons(sp);
            return View("SearchResults", results);
        }

        //Saved search
        // GET: /Persons/SavedSearch/1
        public ActionResult SavedSearch(int id)
        {
            var results = _provider.SearchPersons(id);
            return View("SearchResults", results);
        }

        [HttpPost]
        public ActionResult SaveMySearch(PersonSearchParameters sp, name)
        {
            _provider.SavePersonSearch(sp, name);

            //Show success
            return View();
        }
    }
}
于 2013-04-09T00:52:45.480 回答
1

将您的参数转换为 Base64 字符串。它将帮助您创建任何硬查询,例如http://www.jobs24.co.uk/SearchResults.aspx?query=djAuMXxQUzoxMHx2MC4x¶ms=cXVlcnlmaWx0ZXI6解码 base64 使用此服务http://www.opinionatedgeek.com/DotNet/ Tools/Base64Decode/default.aspx 您也可以查看http://aws.amazon.com/cloudsearch/它可能会让您了解项目中的参数 worh

于 2013-04-07T06:22:53.340 回答
1

像这样的东西可以工作:

将搜索参数存储在 json/xml 中并保存在 DB 表中。1. 当您想要编辑搜索参数时(如果您允许这样做),使用 json/xml 预填充所选参数,以便用户可以编辑条件。2. 当用户想要运行搜索时,从 json 中获取参数并创建/运行查询。

或者

将搜索参数存储在 json/xml 中并保存在 DB 表中,并创建 sql 查询并存储 sql 字符串(在验证参数之后) 1. 当您想要编辑搜索参数时(如果您允许这样做),请使用 json /xml 预填充选定的参数,以便用户可以编辑标准。2. 当用户想要运行搜索时,只需获取保存的查询字符串并执行它。

于 2013-04-12T01:45:57.443 回答