Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在对EF6发出查询之前,始终检查DbSet.Local是安全的_C#_Entity Framework 6 - Fatal编程技术网

C# 在对EF6发出查询之前,始终检查DbSet.Local是安全的

C# 在对EF6发出查询之前,始终检查DbSet.Local是安全的,c#,entity-framework-6,C#,Entity Framework 6,我正在阅读有关使用实体框架6的缓存和性能的文章,我的想法是总是在向数据库发出任何查询之前检查DbSet.Local集合,如果查询的目的是加载单个实体信息。这就是我提出的模式: pubilc TAccount LoadByUsername<TAccount>(string username) { TAccount acc = null; // Check cache. acc = DbEntitySet.Local.FirstOrDefault(a =>

我正在阅读有关使用
实体框架6的缓存和性能的文章,我的想法是总是在向数据库发出任何查询之前检查
DbSet.Local
集合,如果查询的目的是加载单个实体信息。这就是我提出的模式:

pubilc TAccount LoadByUsername<TAccount>(string username)
{
    TAccount acc = null;

    // Check cache.
    acc = DbEntitySet.Local.FirstOrDefault(a => a.Username.Equals(username, StringComparison.CurrentCultureIgnoreCase));

    if (acc == null) {

        // Then try and load from db.
        return await DbEntitySet.FirstOrDefaultAsync(u => u.Username.Equals(username)).WithCurrentCulture();
    }

    return acc;
}
即使
username
参数是
FindById
加载的帐户的用户名,也会导致数据库的4次往返

我的问题是:我是不是发现了什么,还是这种模式不安全?我不确定我是否应该使用这个,因为Identity没有使用任何类似的东西,而且作者显然比我有更多的知识。
DbSet.Local
这样安全吗

--更新


我刚刚发现了一段代码,它可以破解作为参数传递的开放LINQ查询,以检查它是否包含select by id,这样他们就可以在转到db之前检查实体的缓存(通过调用
DbSet.Find
)。所以,我想我有点不明白为什么他们没有把这个想法扩展到“FindByEmail”之类的方法上。真是个有趣的问题,我在这方面遇到了一些问题

对于您发布的示例,它看起来很安全。您正在寻找具有已知键值的单个实体。不过,我想你会发现,在不同的情况下,它并不那么安全

例如,我继承了一些代码,其中存储库首先使用本地(缓存)结果,然后在没有结果的情况下返回到向数据库发出查询:

    public List<T> LoadAll(Expression<Func<T, bool>> expression)
    {
        var localResult = _dbSet.Local.AsQueryable().Where(expression).ToList<T>();

        return localResult.Count > 0 ? localResult : _dbSet.Where(expression).ToList<T>();
    }
public List LoadAll(表达式)
{
var localResult=_dbSet.Local.AsQueryable().Where(expression.ToList();
返回localResult.Count>0?localResult:_dbSet.Where(expression.ToList();
}
这在大多数情况下都很好,但我在发出两个LoadAll请求以获得重叠结果时遇到了一个问题。e、 g.加载图像1和2的图像列表,然后加载图像2和3的图像列表。这两个查询都是使用本地缓存完成的,但第二个查询错误地只包括图像2。映像3尚未在本地缓存中

我要么需要重新编写调用代码以将所有图像预加载到缓存中,要么需要从任何返回列表的方法中删除本地缓存的结果

我看不到一个明显的方法来解决当缓存的查询结果不够好时,发出非缓存的查询


MS发布了一篇文章,其中本地结果直接绑定到UI()。这非常适合您希望能够一次性进行更改并提交所有更改的情况。不太确定它是否能很好地扩展到这一点。

为什么这一点被否决了?无论如何,你提出了一个很好的观点。我想,当您需要一组值时,您需要检查是否存在所有预期结果,否则从数据库中加载它们。困难在于知道“预期结果”是什么。最后,我从任何返回列表的内容中删除了缓存结果。试图从一个表达式中计算出期望的结果是什么太难了。。!
    public List<T> LoadAll(Expression<Func<T, bool>> expression)
    {
        var localResult = _dbSet.Local.AsQueryable().Where(expression).ToList<T>();

        return localResult.Count > 0 ? localResult : _dbSet.Where(expression).ToList<T>();
    }