是DbSet<>。当地的东西特别小心使用? [英] Is DbSet<>.Local something to use with special care?

查看:152
本文介绍了是DbSet<>。当地的东西特别小心使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有关几天,现在,我一直在努力从一个存储库中检索我的实体(的DbContext )。

For a few days now, I have been struggling with retrieving my entities from a repository (DbContext).

我想所有的实体保存在一个原子操作。因此,不同的实体一起代表有价值的东西给我。如果所有的实体是有效,那么我可以将它们保存到数据库中。实体A已被存储在我的库,并且需要被检索到验证实体B

I am trying to save all the entities in an atomic action. Thus, different entities together represent something of value to me. If all the entities are 'valid', then I can save them all to the database. Entity 'a' is already stored in my repository, and needs to be retrieved to 'validate' entity 'b'.

这就是问题出现了。我的仓库依赖于 DbSet< TEntity> 类,它的伟大工程与LINQ2SQL(包括()导航属性例如)。但是,在 DbSet< TEntity> 不包含在了增加了国家实体。

That's where the problem arises. My repository relies on the DbSet<TEntity> class which works great with Linq2Sql (Include() navigation properties e.g.). But, the DbSet<TEntity> does not contain entities that are in the 'added' state.

所以,我有(据我所知)两个选项:

So I have (as far as I know) two options:


  • 使用 ChangeTracker 来查看哪些实体可用,他们查询到基于其 EntityState
  • 一套
  • 使用 DbSet< TEntity方式>。当地属性

  • Use the ChangeTracker to see which entities are available and query them into a set based on their EntityState.
  • Use the DbSet<TEntity>.Local property.

ChangeTracker 似乎涉及一些额外的努力工作得到它的方式,这样我可以用LINQ2SQL到工作包括()导航属性如

The ChangeTracker seems to involve some extra hard work to get it working in a way such that I can use Linq2Sql to Include() navigation properties e.g.

DbSet< TEntity>。当地似乎有点怪我。它可能只是名称。我刚才读,它不是表现非常好东西(超过DbSet<慢;>本身)。不知道这是一个伪命题。

The DbSet<TEntity>.Local seems a bit weird to me. It might just be the name. I just read something that it is not performing very well (slower than DbSet<> itself). Not sure if that is a false statement.

可能有人有显著的EntityFramework经验照耀在这一些轻?什么是明智的路径可循?还是我看到的鬼,我应该始终使用。当地属性?

Could somebody with significant EntityFramework experience shine some light on this? What's the 'wise' path to follow? Or am I seeing ghosts and should I always use the .Local property?

更新与代码示例

    public void AddAndRetrieveUncommittedTenant()
    {
        _tenantRepository = new TenantRepository(new TenantApplicationTestContext());

        const string tenantName = "testtenant";

        // Create the tenant, but not call `SaveChanges` yet until all entities are validated 
        _tenantRepository.Create(tenantName);

        //
        // Some other code
        //

        var tenant = _tenantRepository.GetTenants().FirstOrDefault(entity => entity.Name.Equals(tenantName));

        // The tenant will be null, because I did not call save changes yet,
        // and the implementation of the Repository uses a DbSet<TEntity>
        // instead of the DbSet<TEntity>.Local.
        Assert.IsNotNull(tenant);

        // Can I safely use DbSet<TEntity>.Local ? Or should I play 
        // around with DbContext.ChangeTracker instead?
    }






怎么我的一个例子想用我的



在我的我有这样的方法:

    public IQueryable<TEntity> GetAll()
    {
        return Context.Set<TEntity>().AsQueryable();
    }



我在业务代码以这种方式使用的:

Which I use in business code in this fashion:

    public List<Case> GetCasesForUser(User user)
    {
        return _repository.GetAll().
            Where(@case => @case.Owner.EmailAddress.Equals(user.EmailAddress)).
            Include(@case => @case.Type).
            Include(@case => @case.Owner).
            ToList();
    }

这主要就是为什么我宁愿坚守 DbSet 变量一样。我需要灵活地包含导航属性。如果我使用 ChangeTracker 我检索了实体列表,这并不让我在延迟加载相关的实体在稍后的时间点。

That is mainly the reason why I prefer to stick to DbSet like variables. I need the flexibility to Include navigation properties. If I use the ChangeTracker I retrieve the entities in a List, which does not allow me to lazy load related entities at a later point in time.

如果这是接近难以理解的瞎扯淡,那么请让我知道,这样我可以改进的问题。我迫切需要一个答案。

If this is close to incomprehensible bullsh*t, then please let me know so that I can improve the question. I desperately need an answer.

THX很多提前!

推荐答案

如果您希望能够以易的问题对DbSet查询并把它找到新创建的项目,那么你将需要调用的SaveChanges()创建的每个实体之后。如果您使用的是风格的做法工作单位与持久化实体的工作,其实这是没有问题的,因为你可以有工作单位包住UOW内的所有行动为DB交易(即当UOW创建一个新的TransactionScope创建和调用commit()就可以了,当UOW完成)。采用这种结构,改变被发送到DB中,并且将是可见的DbSet,但对其他UoWs(使用模任何隔离级)不可见。

If you want to be able to 'easily' issue a query against the DbSet and have it find newly created items, then you will need to call SaveChanges() after each entity is created. If you are using a 'unit of work' style approach to working with persistent entities, this is actually not problematic because you can have the unit of work wrap all actions within the UoW as a DB transaction (i.e. create a new TransactionScope when the UoW is created, and call Commit() on it when the UoW completed). With this structure, the changes are sent to the DB, and will be visible to DbSet, but not visible to other UoWs (modulo whatever isolation level you use).

如果你不希望这样的开销,那么你需要修改代码以使在适当的时候利用当地的(可能涉及在看本地,然后发出一个查询对DbSet,如果你没有找到你是什么寻找)。在DbSet的find()方法,也可以在这些情况下非常有用。它将发现通过在本地或在DB主键的实体。所以,如果你只需要找到按主键的项目,这是非常方便(具有性能优势以及)。

If you don't want the overhead of this, then you need to modify your code to make use of Local at appropriate times (which may involve looking at Local, and then issuing a query against the DbSet if you didn't find what you were looking for). The Find() method on DbSet can also be quite helpful in these situations. It will find an entity by primary key in either Local or the DB. So if you only need to locate items by primary key, this is pretty convenient (and has performance advantages as well).

这篇关于是DbSet&LT;&GT;。当地的东西特别小心使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆