簡體   English   中英

存儲搜索參數

[英]Storing search parameters

我目前正在.NET MVC 4中構建一個網站,使用Entity Framework訪問SQL Server。

該網站應具有一個復雜的搜索,為用戶提供多種選擇,創建一個新搜索(免費搜索),從最近的5個搜索中選擇(歷史搜索),從存儲的搜索參數中進行選擇。

我遇到的麻煩是保存搜索參數/ sql字符串的概念,因為它不是基於會話/緩存的,應該存儲在某個地方(SQL Server / MongoDB / XML),我很難充分利用優化路徑(如果是SQL方式),則可以創建一個實體,將搜索參數存儲為實體,然后將其轉換為用於搜索的SQL字符串,或者將其存儲為XML,然后使用JSON進行序列化。

搜索的某些字段與數據庫/實體不完全匹配,需要進行求和/轉換(如將計算為特定時間的小時數)。

我更傾向於充分利用Entity Framework的功能。

希望聽到一些專家的想法,謝謝。

不確定這是否是“最優化的”路徑,但認為實現起來似乎很簡單:

//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方法,這樣就不必在每次想要添加搜索參數時都更改數據庫架構了。


編輯:使用序列化的完整示例

\\ Domain \\ Person.cs

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

\\ Domain \\ 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();
        }
    }
}

\\ Controllers \\ 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();
        }
    }
}

將您的參數轉換為Base64字符串。 它將幫助您創建任何硬查詢,例如, http://www.jobs24.co.uk/SearchResults.aspx? query = djAuMXxQUzoxMHx2MC4x&params = cXVlcnlmaWx0ZXI6解碼base64使用此服務http://www.opinionatedgeek.com/DotNet/您還可以在Tools / Base64Decode / default.aspx上查看http://aws.amazon.com/cloudsearch/,這可能會讓您對項目中的參數有所了解

這樣的事情可能會起作用:

將搜索參數存儲在json / xml中,並保存在數據庫表中。 1.當您要編輯搜索參數時(如果您甚至允許這樣做),請使用json / xml預先填寫所選參數,以便用戶可以編輯條件。 2.當用戶要運行搜索時,請從json中獲取參數並創建/運行查詢。

要么

將搜索參數存儲在json / xml中,並保留在數據庫表中,還創建sql查詢並存儲sql字符串(在驗證參數之后)1.當您要編輯搜索參數(如果允許的話),請使用json / xml以預填寫所選參數,以便用戶可以編輯條件。 2.當用戶要運行搜索時,只需獲取保存的查詢字符串並執行即可。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM