【问题标题】:Writing an extension method for Entity Framework为实体框架编写扩展方法
【发布时间】:2016-07-29 04:02:28
【问题描述】:

我想要一个名为FirstOrDefaultCache()的扩展方法

会检查 dbContext.EntityName.Local.FirstOrDefault(condition),并且仅当 那是空的,检查dbContext.EntityName.FirstOrDefault(condition)

我从另一个帖子中得到了以下内容,它可以正常工作:

public static TEntity FirstOrDefaultCache<TEntity>(this DbSet<TEntity> queryable, 
Expression<Func<TEntity, bool>> condition) where TEntity : class
{
    return queryable
        .Local.FirstOrDefault(condition.Compile()) // find in local cache
           ?? queryable.FirstOrDefault(condition); 
          // if local cache returns null check the db
} 

但是,我不能在 .Include() 之后使用它。

dbContext.EntityName.FirstOrDefaultCache(some condition); 有效,但 dbContext.EntityName.Include(x =&gt; x.NavProperty).FirstOrDefaultCache(some condition); 无效。

【问题讨论】:

  • Include() 方法的返回类型是什么?您可以创建另一个适用于该类型的扩展方法。
  • 这是一个 IQueryable,但是,我无法访问 IQueryable 中的 .Local,并且尝试将其强制转换为 DbSet 会在运行时引发无效强制转换异常。跨度>
  • 您是否尝试过扩展 IQueryable 而不是 DbSet?

标签: c# entity-framework linq linq-to-entities extension-methods


【解决方案1】:

您需要使用IQueryable&lt;T&gt; 才能在IncludeWhere 或任何其他之后使用您的扩展方法。但是由于查询结果没有被缓存,你将无法在你的扩展中使用Local

您的选项是禁用某些包含属性的延迟加载以避免Include

您可以为您的查询实现某种二级缓存。比如this one,不过我没试过,比较老了。

你可以这样使用它:

var result = q.Take(10).FromCache()

在您的情况下,它可能看起来像:

dbContext.EntityName.Include(x => x.NavProperty).FromCache().First(condition)

【讨论】:

  • 好的,我想我现在开始考虑这个问题了。在某些代码情况下,某个实体可能已经在本地的 dbContext 中(因为它刚刚添加),或者它是在之前的运行中添加的(不同的 dbContext),现在驻留在 DB 存储中。我想要一个不错的班轮,先在本地检查,然后再到商店检查。
猜你喜欢
  • 2021-11-05
  • 2017-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多