【发布时间】:2010-08-31 00:26:12
【问题描述】:
我正在开发一个 .NET 4 应用程序、C#、Entity Framework 4、SQL Server 2008。
我的数据库中有 7 个表,每个表代表一个特定级别的位置(国家、州、城市、社区等)。
现在在我的存储库中,我试图定义一个只有一个 Find() 方法的接口契约。为此,我创建了一个名为“Location”的抽象类,POCO 位置都继承自该抽象类。
这是我目前的方法:
public IQueryable<Location> Find()
{
return AllCountries()
.Union(AllStates())
.Union(AllCounties())
.Union(AllCities())
.Union(AllNeigbourhoods())
.Union(AllZipCodes())
.Union(AllStreets());
}
那些内联方法(例如 AllStates)是私有的 IQueryable 方法,例如:
private IQueryable<Location> AllCountries()
{
var db = new MyCustomDataContext();
return db.Countries;
}
这一切都很好,但我不喜欢 Find() 方法中代码的外观。
基本上,我想要一个 Repository 方法,它返回所有国家/城市/州等(作为 IQuerable<Location>)。
这样,我的服务层可以这样做:
var countries = repository.Find(somePredicate).OfType<Country>().ToList();
或者这个:
var countries = repository.Find(somePredicate).OfType<City>().ToList();
所以我只需要声明一个 Find 方法。您可以将 Location 类视为我的“聚合根”。
不使用抽象类,这就是我的存储库合约的样子:
IQueryable<City> FindCities();
IQueryable<State> FindStates();
IQueryable<Country> FindCountries();
....
糟糕!
这是我的存储库合同目前的样子(我想保持这种方式):
IQueryable<Location> Find();
那么,有什么比拥有所有这些工会更好的想法呢? IQueryable<T> 扩展方法,可以动态链接多个 IQueryable 的?
请记住,我还有一个执行过滤/收集投影(延迟执行)的服务层。存储库需要返回“查询”,而不是具体的集合。
感谢您的帮助。
【问题讨论】:
-
我不会说你的设计是“错误的”......让我们说“我不明白”。话虽如此,您似乎想要执行以下搜索:特定城市的所有街道;涉及特定街道的所有邮政编码;特定县的所有城市和社区;特定社区的所有街道;等等。那么接近吗?
-
@Neil T - 现场。我希望能够根据谓词搜索任何“位置”(城市/国家/州)。我不想拥有一个包含 IQueryable
FindCities()、IQueryable FindStates() 等的存储库。我想要一个能够返回任何位置类型的集合的 Find() 方法。 -
Location也是实体类吗?如果是这样,为什么不能从存储库中检索所有Location实例? -
@Jacob。不,位置不是实体(实体数据模型中不存在)。它是一个仅用于存储库/服务层抽象的抽象类。所有 POCO 都继承自它,这就是允许使用 IQueryable
的原因。
标签: .net linq extension-methods repository-pattern iqueryable