Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.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
在NHibernate中查询对象存在性的最快方法_Nhibernate - Fatal编程技术网

在NHibernate中查询对象存在性的最快方法

在NHibernate中查询对象存在性的最快方法,nhibernate,Nhibernate,我正在寻找检查对象是否存在的最快方法。 这个场景非常简单,假设有一个目录工具,可以读取当前的硬盘。当找到一个目录时,应该创建它,或者,如果已经存在,则更新它 首先,让我们只关注创建部分: public static DatabaseDirectory Get(DirectoryInfo dI) { var result = DatabaseController.Session .CreateCriteria(typeof

我正在寻找检查对象是否存在的最快方法。 这个场景非常简单,假设有一个目录工具,可以读取当前的硬盘。当找到一个目录时,应该创建它,或者,如果已经存在,则更新它

首先,让我们只关注创建部分:

    public static DatabaseDirectory Get(DirectoryInfo dI)
    {
        var result = DatabaseController.Session
                      .CreateCriteria(typeof (DatabaseDirectory))
                      .Add(Restrictions.Eq("FullName", dI.FullName))
                      .List<DatabaseDirectory>().FirstOrDefault();

        if (result == null)
        {
            result = new DatabaseDirectory
                         {
                             CreationTime = dI.CreationTime,
                             Existing = dI.Exists,
                             Extension = dI.Extension,
                             FullName = dI.FullName,
                             LastAccessTime = dI.LastAccessTime,
                             LastWriteTime = dI.LastWriteTime,
                             Name = dI.Name
                         };
        }
        return result;
    }
publicstaticdatabasedirectory-Get(DirectoryInfo-dI)
{
var result=DatabaseController.Session
.CreateCriteria(类型(数据库目录))
.Add(Restrictions.Eq(“全名”,dI.FullName))
.List().FirstOrDefault();
如果(结果==null)
{
结果=新数据库目录
{
CreationTime=dI.CreationTime,
Existing=dI.Exists,
扩展=dI.扩展,
FullName=dI.FullName,
LastAccessTime=dI.LastAccessTime,
LastWriteTime=dI.LastWriteTime,
Name=dI.Name
};
}
返回结果;
}
这是关于以下方面的方法:

  • 速度
  • 关注点分离
我想到的是:扫描总是“作为一个整体”进行的。也就是说,在扫描驱动器C的过程中,我知道数据库中没有添加任何新的内容(从其他进程)。因此,最好在扫描之前“缓存”所有现有目录,并以这种方式查找它们。另一方面,这可能不适用于大型数据集,如文件(将是600.000或更多)

也许使用“索引列”或类似的东西可以获得一些性能提升,但我对这个主题不太熟悉。如果有人有一些参考资料,只要给我指出正确的方向

谢谢, 克里斯

PS:我正在使用NHibernate、流畅的界面、自动映射和SQL Express(可以切换到完整的SQL)

注意: 在给定的问题中,路径不是数据库中的ID。ID是自动递增的,我无法更改此要求(其他原因)。所以真正的问题是,检查对象存在的最快方法是什么?如果ID未知,只检查该对象的属性


批处理可能是可能的,通过选择一个大的组,比如“从C:Testfiles开始”,但问题仍然存在,我如何提前知道这个集合有多大。我不能选择“max 1000”并签入这个缓冲字典,因为我可能会“点击搜索目录旁边”。。。我希望这个问题是清楚的。最重要的一点是,缓冲真的对性能有这么大的影响吗。如果是这样的话,在字典中加载整个数据库是否有意义,只包含路径和ID(我认为,即使有1.000.000个对象,这也可以)

首先,我强烈建议您(任何使用NH的人)阅读Ayende的文章

在您的情况下,由于需要检查是否存在,我将使用
.Get(id)
而不是查询来选择单个对象

但是,我想知道您是否可以利用您的问题领域的一些知识来提高性能。如果要扫描整个驱动器,并检查数据库中是否存在每个目录,则通过执行批量操作可能会获得更好的性能。也许可以创建一个只包含
数据库目录
对象主键的DTO对象,以进一步最小化数据传输/处理。比如:

Dictionary<string, DirectoryInfo> directories;
session.CreateQuery("select new DatabaseDirectoryDTO(dd.FullName) from DatabaseDirectory dd where dd.FullName in (:ids)")
    .SetParameterList("ids", directories.Keys)
    .List();
字典目录;
CreateQuery(“从数据库目录dd中选择新的数据库目录dd(dd.FullName),其中dd.FullName位于(:id)”)
.SetParameterList(“ID”,目录.key)
.List();
然后只需删除与返回的ID值匹配的元素,即可获得不存在的目录。您可能必须根据输入集的大小(几乎可以肯定的是,对于文件),将流程分成更小的批


至于分离关注点,只需将操作保持在存储库级别。有一个类似于
SyncDirectories
的方法,它接受一个集合(如果您遵循上面的方法,可能是一个
Dictionary
),用于处理更新数据库的过程。这样,您的高级应用程序逻辑就不必担心它是如何工作的,而且如果您将来找到一种更快的方法,也不会受到影响。

好的,谢谢您的回答。主体部分很有趣,我必须对此进行详细研究。第一个建议的问题是:我不知道ID。路径不是ID,我会在上面的帖子中添加这一点,让它更清楚。谢谢你的回答。。。