您的位置:首页 > 数据库

Linq to sql 几个需要注意的地方

2010-07-15 21:47 701 查看
1. RepositoryBase<T> : IQueryable<T>
大部分同学使用Linq to sql都会自己写一个RepositoryBase<T>,如果继承至IQueryable<T>会让你用的很舒畅。
比如:
Repository.GetAll().Count(it=>...) 与 Repository.Count(it=>...)
你会更喜欢什么呢?当然这也算个人喜好吧。

2. 如何判断实体状态
如何判断实体是直接New出来的,还是从数据库中Get出来的,由于没有像Entity Framework中的EntityState,Linq to sql要怎么判断呢?
测试: 
直接New一个实体,执行OnCreated()

从数据库中Get一个实体,执行OnLoaded(), OnCreated()

这样我们就可以在OnLoaded()上做判断了。

public partial class Entity {

partial void OnLoaded() {

IsNew = false;

}

private bool _isNew = true;

public bool IsNew

{

get { return _isNew; }

set { _isNew = value; }

}

}

3. Lazy load
3.1 Lazy load给我们带了非常大的方便,不过有时也藏着危险,所以我们在写相关语句的时候也需要留意一下,有没有可以优化的方法。
比如在循环语句里写Lazy load的时候,就应该考虑会不会每次都发SQL请求呢?
3.2 this.Product.Categories.Any(it=>it...) 大家想想会发出什么SQL请求呢?

EntitySet<Category> Categories // 是EntitySet<T>

EntitySet<TEntity> : IList, ICollection, IList<TEntity>, ICollection<TEntity>, IEnumerable<TEntity>, IEnumerable, IListSource where TEntity : class // 并没有实现IQueryable

所以会发一条Sql语句,把关联的Category都取出来。然后调用IEnumerable这个集合的Any扩展。
而不是直接发一条关于Any的Sql语句。
  3.3 Lazy load是会缓存的
    user.Role
    user.Role
    user.Role
    // 调用三次,但实践上只会发送一次请求,不要以为Linq to sql很笨。
    

4. 立即加载
有Lazy load,当然也就有立即加载。
Linq to sql的立即加载都是使用DataLoadOptions下的LoadWith<T>与AssociateWith<T>,而这个设置必须在DataContext返回数据之前被设置。

应该会有很多同学和我一样把DataContext放在上下文中,如果是非web请求,就放在CallContext中,这样一个请求下来DataContext就是唯一的。

比如:
后台一个取产品列表的页面,现在要立即加载分类。

首先进入该页面,进行用户验证,这已经返回了一次数据, 取产品列表,在DataContext上设置LoadWith<Product>(it=>it.Category)出错了。

所以我们只能把LoadWith<Product>(it=>it.Category)搬到构造DataContext的地方,这样就可以了。
虽然代码上不直观,不过性能上好像没有什么影响,也没有产生额外的SQL语句,只有在加载Product的时候,会inner join下Category。

   当然当你想取Product不加载Category时,抱歉,没办法了。。。

5. == NULL 并不等价于 is NULL
5.1
int? parentId = null;
Repositoy.Count(it=>it.ParentId == parentId); // == NULL

5.2
Repositoy.Count(it=>it.Parent == null); // is NULL

第1条语句结果始终为0。== NULL 不要用切记切记。

你可以使用
Repository.Count(it=>object.Equals(it.ParentId, parentId));
或者 Repository.Count(it=>parentId == null ? it.ParentId == null : it.ParentId == parentId);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: