EF架构~为IEnumerable接口添加增删查等操作,原因是IEnumerable导航属性更放心
对EF开发来说,导航属性肯定都用过,事实上,它是由VS IDE工具根据你的数据库关系结构自动生成的外键属性,在类视图中可以看到相关属性,它是以外键表名来标识的,如果是一对多的关系,那么,它会为属性加上ICollection泛型集合用来标识,而今天我们要说的当然不是自动生成的,而是手动加的属性,这样属性需要我们手动进行join,然后把它按需赋值,而使用include当然是无效的,呵呵。
一般地,我们习惯上把集合属性定义为List<T>,但是,对于linq to entities来说,这个东西并不是很受欢迎,而标准结果集大家都知道是IEnumerable<T>,它是所有集合的基类,自身只提供了集合遍历的方法,这也是我们不用它作为导航属性的原因,因为我们一般需要为导航集合赋值的,而使用IEnumerable赋值就比较麻烦,需要借助List等集合。
引入IEnumerable的原因主要是List无法实现一个复杂的查询,如图:
这个查询返回一个派生类型,下面的复杂查询将会用到上面的结果,而这时,List类型的导航属性将是不被允许的
我们通过监视器可以看到,查询返回的默认是IEnumerable,所以,我们要属性改为IEnumerable,结果当然是正常的
而我们之前不用IEnumerable的原因,就是因为它的方法太单调了,没有添加,移除,查找等方法,而这时,不用它又不行,所以,只能把它进行扩展了,呵呵
扩展方法如下:
/// <summary> /// IEnumerable接口的扩展方法,支持它的实现类是List的情况 /// </summary> public static class IEnumerableExtensions { /// <summary> /// 向集合中添加元素 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="collection"></param> /// <param name="value"></param> public static void Add<T>(this IEnumerable<T> collection, T value) { (collection as List<T>).Add(value); } /// <summary> /// 从集合中删除元素 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="collection"></param> /// <param name="value"></param> public static void Remove<T>(this IEnumerable<T> collection, T value) { (collection as List<T>).Remove(value); } /// <summary> /// 检索集合中是否包含某个元素 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="collection"></param> /// <param name="value"></param> /// <returns></returns> public static bool Contains<T>(this IEnumerable<T> collection, T value) { return (collection as List<T>).Contains(value); } }
调用也是十分简单,和List类型的一样样,呵呵,舒服!