You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#查询Win10 Photos SQLite数据库缺失NoCaseUnicode排序规则的解决问询

解决Windows 10 Photos SQLite数据库在C#中缺失NoCaseUnicode排序规则的问题

我来帮你搞定这个问题——Windows Photos的SQLite数据库用了自定义的NoCaseUnicode排序规则,这个规则是Photos应用自己实现的,SQLite默认没有内置,所以你的C#程序执行关联查询时才会报错。下面是几个可行的解决方案,按推荐程度排序:

1. 在C#中注册自定义的NoCaseUnicode排序规则(推荐)

这是一劳永逸的方法,只需要在打开数据库连接后注册一次自定义规则,就能让SQLite识别NoCaseUnicode,不需要修改任何SQL语句。我们可以用.NET的全球化API模拟这个规则的核心行为:不区分大小写的Unicode字符串比较。

using System.Data.SQLite;
using System.Globalization;

public void QueryPhotosDatabase()
{
    // 替换为你的Photos数据库实际路径
    var dbPath = @"C:\Users\<YourUsername>\AppData\Local\Packages\Microsoft.Windows.Photos_8wekyb3d8bbwe\LocalState\MediaDb.sqlite";
    var connectionString = $"Data Source={dbPath};Version=3;";

    using (var conn = new SQLiteConnection(connectionString))
    {
        conn.Open();

        // 注册自定义的NoCaseUnicode排序规则,模拟不区分大小写的Unicode比较
        conn.CreateCollation("NoCaseUnicode", (string x, string y) =>
        {
            if (x == null && y == null) return 0;
            if (x == null) return -1;
            if (y == null) return 1;

            // 使用不变文化的不区分大小写比较,和Photos的规则行为一致
            return CultureInfo.InvariantCulture.CompareInfo.Compare(x, y, CompareOptions.IgnoreCase);
        });

        // 现在可以正常执行带关联的查询了,不需要额外加COLLATE BINARY
        var query = @"
            SELECT i.Item_FileName 
            FROM Item i 
            JOIN AlbumItem ai ON i.ItemId = ai.ItemId 
            WHERE i.Item_FileName = '2.jpg'";

        using (var cmd = new SQLiteCommand(query, conn))
        using (var reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                Console.WriteLine($"找到文件:{reader["Item_FileName"]}");
            }
        }
    }
}

这个方案的好处是完全贴合数据库的默认配置,后续所有查询、关联操作都能正常使用NoCaseUnicode规则,不需要改动SQL语句。

2. 在所有查询和关联中显式指定COLLATE BINARY

如果你不想写C#代码注册规则,可以在SQL语句的每个涉及排序规则的地方(包括JOIN的ON子句)显式加上COLLATE BINARY,覆盖表的默认排序规则:

SELECT i.Item_FileName 
FROM Item i 
JOIN AlbumItem ai ON i.ItemId COLLATE BINARY = ai.ItemId COLLATE BINARY 
WHERE i.Item_FileName = '2.jpg' COLLATE BINARY;

注意:必须给JOIN的关联字段也加上COLLATE BINARY,因为关联时SQLite会使用字段的默认排序规则(也就是缺失的NoCaseUnicode),不加的话还是会触发报错。这个方案适合简单查询,但复杂查询会让SQL语句变得冗长。

3. 创建临时视图统一转换排序规则

对于复杂的多表查询,你可以在连接数据库后创建临时视图,把需要的表的所有字段都转换为COLLATE BINARY,然后用视图来执行查询:

using (var conn = new SQLiteConnection(connectionString))
{
    conn.Open();

    // 创建Item表的临时视图,统一转换为BINARY排序规则
    var createItemViewCmd = new SQLiteCommand(@"
        CREATE TEMP VIEW Item_Binary AS 
        SELECT 
            ItemId COLLATE BINARY AS ItemId,
            Item_FileName COLLATE BINARY AS Item_FileName,
            Item_Path COLLATE BINARY AS Item_Path
            -- 其他需要用到的字段也按此格式添加
        FROM Item;", conn);
    createItemViewCmd.ExecuteNonQuery();

    // 同样创建AlbumItem表的临时视图
    var createAlbumViewCmd = new SQLiteCommand(@"
        CREATE TEMP VIEW AlbumItem_Binary AS 
        SELECT 
            ItemId COLLATE BINARY AS ItemId,
            AlbumId COLLATE BINARY AS AlbumId
        FROM AlbumItem;", conn);
    createAlbumViewCmd.ExecuteNonQuery();

    // 现在查询视图就不会报错了
    var query = @"
        SELECT i.Item_FileName 
        FROM Item_Binary i 
        JOIN AlbumItem_Binary ai ON i.ItemId = ai.ItemId 
        WHERE i.Item_FileName = '2.jpg'";

    // 执行查询并处理结果...
}

这个方案把转换逻辑封装在视图里,查询语句会更简洁,但每次打开连接都需要重新创建临时视图。

总结

优先推荐方案1,注册自定义排序规则后,你的C#程序就能完全适配Windows Photos的数据库,不需要修改任何查询逻辑。如果只是临时执行简单查询,方案2更快捷;复杂多表查询可以考虑方案3。

内容的提问来源于stack exchange,提问作者SimonKravis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:52:30