加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 是DbSet <>.本地的东西要特别小心使用?

发布时间:2020-12-15 03:54:49 所属栏目:百科 来源:网络整理
导读:几天以来,我一直在努力从存储库(DbContext)检索我的实体. 我试图将所有的实体保存在原子动作中.因此,不同的实体一起代表了对我有价值的东西.如果所有实体都是“有效”,那么我可以将它们全部保存到数据库中.实体’a’已经存储在我的存储库中,需要检索到’验证
几天以来,我一直在努力从存储库(DbContext)检索我的实体.

我试图将所有的实体保存在原子动作中.因此,不同的实体一起代表了对我有价值的东西.如果所有实体都是“有效”,那么我可以将它们全部保存到数据库中.实体’a’已经存储在我的存储库中,需要检索到’验证’实体’b’.

那就是问题的出现.我的存储库依赖于DbSet< TEntity>类与Linq2Sql(Include()导航属性相似).但是,DbSet< TEntity>不包含处于“已添加”状态的实体.

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

>使用ChangeTracker查看哪些实体可用,并根据其EntityState将它们查询到一个集合中.
>使用DbSet< TEntity> .Local属性.

ChangeTracker似乎需要一些额外的努力才能使其工作,使我可以使用Linq2Sql来包含()导航属性,例如

DbSet< TEntity>.本质似乎对我来说有点怪异.它可能只是这个名字.我只是读一些它不能很好地执行(比DbSet本身慢)的东西.不确定是否是虚假陈述.

有些具有重要实体框架经验的人可以在这上亮一点吗?什么是“明智”的路径呢?或者我看到鬼,我应该总是使用.Local属性?

更新代码示例:

出现什么问题的例子

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();
    }

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

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,我检索列表中的实体,这不允许我在稍后的时间点延迟加载相关实体.

如果这是接近难以理解的斗牛士,那么请让我知道,以便我可以改善这个问题.我迫切需要一个答案.

Thx提前很多!

解决方法

如果您想要轻松地对DbSet发出查询,并找到新创建的项目,那么在创建每个实体后,您将需要调用SaveChanges().如果您使用“工作单位”风格的方法来处理持久化实体,这其实并没有问题,因为您可以将工作单元包含在UoW中的所有操作作为DB事务(即,当UoW创建新的TransactionScope被创建,并在UoW完成时调用Commit()).使用此结构,更改将发送到DB,并且将对DbSet可见,但对其他UoW(对任何使用的隔离级别模数)都不可见.

如果你不想要这个开销,那么你需要修改你的代码,以便在适当的时候使用Local(可能涉及到Local,然后在DbSet发出一个查询,如果你没有找到你的正在寻找).在这些情况下,DbSet上的Find()方法也是非常有用的.它将通过主键在本地或数据库中找到一个实体.所以如果你只需要通过主键找到项目,这样很方便(也有性能优势).

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读