我是SPA和实体框架的新手,我有一个关于正确/首选方式的问题。
我有一个网页可以通过一些过滤器搜索客户(如姓名,姓氏,生日,电话号码)。
使用ajax,我从View传递给一个ViewModel对象,如下所示:
public class CustomerSearch
{
public string Name { get; set; }
public string Surname { get; set; }
public DateTime? Birthday{ get; set; }
public string Phone{ get; set; }
}
进入控制器我有这种搜索方法:
public List<CustomerList> GetCustomersList(CustomerSearch cs)
{ ..... }
在我的应用程序中,还有DataAccess对象。
现在,问题是:如何在智能模式下对数据库进行查询?
我认为有些情况,但我不知道哪种情况最适合分层。
哪种方法最好?
提前致谢。
丹尼尔
答案 0 :(得分:0)
我建议您提出第一个选项,原因如下:
如果可能的搜索查询数量增加,您的第二个选项可能需要很多参数。通常不建议使用大量参数,因为它会导致可读性问题。 (例如,调用具有30个参数的方法)
您的第三个选项将无法创建像'1998年的BirthDate'或'Surname以Q开头'的查询。
通过专门为查询目的创建一个类,您可以执行以下操作:
public class CustomerQuery
{
public string Name { get; set; }
public DateTime? BirthDay { get; set; }
internal IQueryable<Customer> Apply(IQueryable<Customer> query)
{
var result = query;
if (!string.IsNullOrWhiteSpace(Name))
{
result = result.Where(c => c.Name == Name);
}
if (BirthDay.HasValue)
{
result = result.Where(c => c.BirthDay == BirthDay.Value);
}
return result;
}
}
特别注意internal
方法的Apply
可见性。如果在数据访问层中定义此类并且这是在单独的C#项目中定义的,则Apply
方法仅对此数据访问层可见,而不对GUI项目可见。
调用它将是:
public List<Customer> GetCustomersList(CustomerQuery customerQuery)
{
using (var context = new MyDbContext())
{
var customers = context.Customers;
return customerQuery.Apply(customers).ToList();
}
}
这可以进一步扩展到支持例如不同类型的字符串搜索(包含,StartsWith等):
public enum TextFilterType
{
StartsWith,
EndsWith,
Contains,
ExactMatch
}
public class StringQuery
{
private readonly string _value;
private readonly TextFilterType _filterType;
public StringQuery(string value, TextFilterType filterType)
{
_value = value;
_filterType = filterType;
}
public string Value
{
get { return _value; }
}
public TextFilterType FilterType
{
get { return _filterType; }
}
}
如果我们将其应用于CustomerQuery
类型:
public class CustomerQuery
{
public StringQuery Name { get; set; }
}
然后,您查看FilterType
的{{1}}属性,了解是否需要执行StringQuery
,Contains
等。