我正在研究.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?
记住我还有一个服务层,它执行过滤/收集预测(延迟执行)。存储库需要返回“查询”,而不是具体的集合。
感谢帮助。
答案 0 :(得分:1)
我假设在两个单独的表中不存在相同的逻辑实体(例如,“city”不是“state”)。在这种情况下,您更适合使用Concat
而不是Union
。
简短的帮助方法将使调用看起来更好(警告:未经测试):
// (Defined in the static class MyHelpers)
// Concatenate all sequences into one.
public IQueryable<T> ConcatAll<T>(this IQueryable<T> first,
params IQueryable<T>[] others)
{
var ret = first;
foreach (var other in others)
{
ret = ret.Concat(other);
}
return ret;
}
...
public IQueryable<Location> Find()
{
return MyHelpers.ConcatAll(
AllCountries(),
AllStates(),
AllCounties(),
AllCities(),
AllNeigbourhoods(),
AllZipCodes(),
AllStreets());
// OR:
return AllCountries().ConcatAll(
AllStates(),
AllCounties(),
AllCities(),
AllNeigbourhoods(),
AllZipCodes(),
AllStreets());
}
答案 1 :(得分:1)
实体框架允许您将表映射到使用继承的数据模型。如果数据库中有一个包含所有公共字段的Location
表,并且每个子位置类(例如City
)都有一个指向该Location
表的外键,那么从存储库中检索Location
个对象,您还应该接收继承类的实例。
如果Location
中没有公共字段,那么拥有联合集合似乎没什么好处。