Linq to sql 关于使用洋葱架构过滤数据和代码重用的建议
以下是我的问题,然后我将向您介绍这些问题的背景: 我更喜欢使用方法2作为我的应用程序设计,那么有没有一种方法可以提供类似方法1的过滤,而不引入对非业务代码的引用,也不允许访问核心项目中的数据库模型 如何处理代码重用?每个对象的名称空间类似于Project.Core.Domain或Project.Core.Services,但如果您觉得奇怪,请将名称空间设置为CompanyName.Core.Domain,而不将其存储在该项目中。目前,我正在复制源代码文件并重命名名称空间以处理此问题,但我想知道是否有一种组织方式来处理此问题或其他我没有想到的问题 我正在使用的技术: ASP.NETMVC3 Linq到SQL 结构图 最小起订量 MSTest 方法1: 以下是我如何设置我的web项目: 数据项目将包含所有存储库和Linq数据上下文。在存储库中,我将使用IQueryable从数据库返回对象集合Linq to sql 关于使用洋葱架构过滤数据和代码重用的建议,linq-to-sql,asp.net-mvc-3,filtering,code-reuse,onion-architecture,Linq To Sql,Asp.net Mvc 3,Filtering,Code Reuse,Onion Architecture,以下是我的问题,然后我将向您介绍这些问题的背景: 我更喜欢使用方法2作为我的应用程序设计,那么有没有一种方法可以提供类似方法1的过滤,而不引入对非业务代码的引用,也不允许访问核心项目中的数据库模型 如何处理代码重用?每个对象的名称空间类似于Project.Core.Domain或Project.Core.Services,但如果您觉得奇怪,请将名称空间设置为CompanyName.Core.Domain,而不将其存储在该项目中。目前,我正在复制源代码文件并重命名名称空间以处理此问题,但我想知道是
public IQueryable<Document> List()
{
return from d in db.Documents
select d;
}
这允许我设置静态方法的过滤器。这些数据也存储在数据项目中
public static IQueryable<Document> SortByFCDN(this IQueryable<Document> query)
{
return from d in query
orderby d.ID
select d;
}
在服务层中,过滤器可以这样应用
public IPagedList<Document> ListByFCDN(int page, IConfiguration configuration)
{
return repository.List().SortByFCDN().ToPagedList(page, configuration.PageSize, configuration.ShowRange);
}
因此,存储库只需提供一个ListAll方法,该方法将所有项目作为IQueryable对象返回,然后服务层将确定如何在返回数据子集之前对其进行过滤
我喜欢这种方法,它使我的存储库更干净,同时将大部分代码保留在服务中
方法2
以下是我当前设置web项目的方式:
使用洋葱架构:
核心:包含业务域模型、应用程序的所有接口和服务类实现。
基础架构:包含存储库实现、Linq数据上下文和映射类,以将Linq数据库模型映射到业务模型。
因为我将业务代码与数据库代码分离,所以我不想在核心项目中添加对Linq之类的东西的引用,以获得对IQueryable的访问。因此,我必须在存储库层执行过滤,将数据库模型映射到域模型,然后将域对象集合返回到服务层。这可能会将其他方法添加到我的存储库中。这就是我最终要做的: 1在核心项目中创建了筛选枚举对象
public enum FilterType
{
SortFCDN
}
2在核心项目的服务类中,执行以下操作:
public IPagedList<Document> ListByFCDN(int page)
{
Dictionary<FilterType, object> filters = new Dictionary<FilterType, object>();
filters.Add(FilterType.SortFCDN, "");
return repository.List(page, filters);
}
3在基础设施项目下的存储库中:
public IPagedList<Document> List(int page, Dictionary<FilterType, object> filters)
{
//Query all documents and map to the model.
return (from d in db.DbDocuments
select d).Filter(filters).Map(
page,
configuration.Setting("DefaultPageSize", true).ToInt(),
configuration.Setting("DefaultShowRange", true).ToInt());
}
public static class DocumentFilters
{
public static IQueryable<DbDocument> Filter(this IQueryable<DbDocument> source, Dictionary<FilterType, object> filters)
{
foreach (KeyValuePair<FilterType, object> item in filters)
{
switch (item.Key)
{
case FilterType.SortFCDN:
source = source.SortFCDN();
break;
}
}
return source;
}
public static IQueryable<DbDocument> SortFCDN(this IQueryable<DbDocument> source)
{
return from d in source
orderby d.ID
select d;
}
}
4在基础设施项目中创建过滤器类:
public IPagedList<Document> List(int page, Dictionary<FilterType, object> filters)
{
//Query all documents and map to the model.
return (from d in db.DbDocuments
select d).Filter(filters).Map(
page,
configuration.Setting("DefaultPageSize", true).ToInt(),
configuration.Setting("DefaultShowRange", true).ToInt());
}
public static class DocumentFilters
{
public static IQueryable<DbDocument> Filter(this IQueryable<DbDocument> source, Dictionary<FilterType, object> filters)
{
foreach (KeyValuePair<FilterType, object> item in filters)
{
switch (item.Key)
{
case FilterType.SortFCDN:
source = source.SortFCDN();
break;
}
}
return source;
}
public static IQueryable<DbDocument> SortFCDN(this IQueryable<DbDocument> source)
{
return from d in source
orderby d.ID
select d;
}
}
然后,服务层核心项目可以决定应用哪些过滤器,并在查询执行之前将这些过滤器传递给存储库基础设施项目。只要每个过滤器类型只应用一个过滤器,就可以应用多个过滤器
过滤器字典可以保存过滤器的类型以及需要传递到过滤器中的任何值/对象。也可以很容易地添加新的过滤器