1

現在、Entity Framework を使用して SQL Server にアクセスし、.NET MVC 4 で Web サイトを構築しています。

Web サイトには、ユーザー向けに複数の選択肢がある複雑な検索、新しい検索の作成 (無料検索)、過去 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て通常どおりメソッドに渡すこともできます。そうすれば、検索パラメーターを追加するたびに DB スキーマを変更する必要がなくなります。


編集:シリアライゼーションを使用した完全な例

\ドメイン\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();
        }
    }
}

\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();
        }
    }
}
于 2013-04-09T00:52:45.480 に答える