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

Xamarin C#运行时从数据库更新嵌入资源RESX文件方案咨询

嵌入资源RESX无法直接更新,这是可行方案

当RESX被标记为嵌入资源后,它会被编译进程序集(.dll/.exe),运行时程序集是只读的,所以没法直接修改嵌入的RESX内容。下面是几种替代方案:

方案1:内存字典覆盖(推荐,不修改文件)

读取嵌入RESX的内容到内存字典,再用数据库的数据覆盖或新增键值对,后续本地化时直接从这个内存字典取值:

// 初始化ResourceManager读取嵌入资源
var resourceManager = new ResourceManager("YourProjectNamespace.Resources", Assembly.GetExecutingAssembly());
var resourceSet = resourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);

// 转成可修改的字典
var resourceDict = resourceSet.Cast<DictionaryEntry>()
    .ToDictionary(entry => entry.Key.ToString(), entry => entry.Value.ToString());

// 从数据库获取更新数据(自行实现GetUpdatedResourcesFromDb方法)
var dbUpdates = GetUpdatedResourcesFromDb();
foreach (var update in dbUpdates)
{
    if (resourceDict.ContainsKey(update.Key))
    {
        resourceDict[update.Key] = update.Value;
    }
    else
    {
        resourceDict.Add(update.Key, update.Value);
    }
}

// 使用时直接从字典取
var localizedContent = resourceDict["WelcomeMessage"];

方案2:将RESX改为非嵌入资源,运行时修改文件

如果必须保留RESX文件形式,把RESX的生成操作改成「内容」,「复制到输出目录」设为「始终复制」,这样文件会被放到输出目录,运行时可以用ResXResourceWriter修改:

// 读取现有RESX文件内容
var resxPath = Path.Combine(AppContext.BaseDirectory, "Resources.resx");
var existingEntries = new List<DictionaryEntry>();
using (var reader = new ResXResourceReader(resxPath))
{
    existingEntries = reader.Cast<DictionaryEntry>().ToList();
}

// 合并数据库更新
var dbUpdates = GetUpdatedResourcesFromDb();
foreach (var update in dbUpdates)
{
    var targetEntry = existingEntries.FirstOrDefault(e => e.Key.ToString() == update.Key);
    if (targetEntry.Key != null)
    {
        targetEntry.Value = update.Value;
    }
    else
    {
        existingEntries.Add(new DictionaryEntry(update.Key, update.Value));
    }
}

// 写入回RESX文件
using (var writer = new ResXResourceWriter(resxPath))
{
    foreach (var entry in existingEntries)
    {
        writer.AddResource(entry.Key.ToString(), entry.Value.ToString());
    }
}

注意:这种方式需要程序有文件写入权限,Web应用可能需要重启应用池才能加载新的RESX内容。

方案3:完全用数据库存储本地化资源

放弃RESX,直接把所有本地化键值对存在数据库(比如建表Localization,字段:CultureCode, ResourceKey, ResourceValue),读取时直接查数据库,还可以加内存缓存提升性能:

// 示例:从数据库读取本地化内容
public string GetLocalizedValue(string key, string culture)
{
    // 这里可以加缓存逻辑,避免每次查库
    using (var db = new YourDbContext())
    {
        var resource = db.Localization
            .FirstOrDefault(r => r.ResourceKey == key && r.CultureCode == culture);
        return resource?.ResourceValue ?? key; // 找不到返回键名作为 fallback
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 08:07:33