如果我设计我的数据库层,以便我可以在linq-to-sql或nhibernate实现之间交换它,我必须针对接口进行编码。
这意味着linq和nhibernate之间的返回类型必须相同,即List等。
列表类型是否相同?
答案 0 :(得分:2)
如果封装了数据库访问,例如使用存储库模式,则可以让存储库实现一个公共接口,并让方法返回您选择用作返回类型的类型,例如IEnumerable(T)或IList( T)。
由于IList(T)实现IEnumerable(T),因此在该方向上没有问题。如果你有IEnumerable(T),你可以在IEnumerable(T)上使用ToList()扩展方法来获取List(T)。 IQueryable(T)实现IEnumerable(T)到ToList()在这种情况下工作正常。
这样的事情:
public interface IFooRepository
{
IList<Foo> GetAll();
// ...
}
public class NHibernateFooRepository : IFooRepository
{
//...
public IList<Foo> GetAll()
{
return Session.CreateCriteria(typeof(Foo)).List<Foo>();
}
}
public class LinqToSqlFooRepository : IFooRepository
{
//...
public IList<Foo> GetAll()
{
var foos = from Foo f in context.Foos select f;
return foos.ToList();
}
}
答案 1 :(得分:1)
IQueryable<T>
结果编写相当多的代码,这些结果应该在大多数情况下进行转换。 (虽然您应该事先对此进行测试,因为每个提供程序的LINQ支持都不同。)
但是,默认情况下,实体类型的1- *关系可能不会共享相同的类型(在LINQ-to-SQL中通常为EntitySet<T>
,在NHibernate中为IList<T>
),但如果你可以强制LINQ-to-SQL和NHibernate使用IList<T>
或IEnumerable<T>
来实现这种关系,这也应该有效。
如果你只是在编译时兼容性之后,各种集合类型之间的区别不应该是一个问题,只要你坚持通用的。例如,如果您的NHibernate映射使用IList<T>
而LINQ-to-SQL使用EntitySet<T>
,那么只需坚持IList<T>
方法,您就会安全。
请注意每个框架的懒惰和急切加载差异。
答案 2 :(得分:0)
NHibernate默认为集合返回IList,遗憾的是很多linq表达式对它们不起作用。我不确定是否有办法改变NHibernate返回类型,因为我还没有真正研究过它。