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

Xamarin Forms SQLite是否有EF中CurrentValues.SetValues的等效更新方式?

在Xamarin Forms中使用SQLite仅更新模型特定字段

你当前的更新方式会把未赋值的字段设为null,这是因为UpdateAsync会将传入的实体完整覆盖到数据库中。下面提供几种解决思路,实现仅更新指定字段:

方法1:先查询再更新(最直观)

先从数据库取出目标实体,只修改需要更新的字段,再执行更新操作,这样未修改的字段会保留原有值:

// 先获取数据库中已存在的实体
var existingAuth = await validateToken.GetById(defaultUser.pid);
// 仅更新需要修改的字段
existingAuth.defaultUser = "N";
// 执行更新
await validateToken.Update(existingAuth);

// 你的Update方法无需修改
public async Task<int> Update(T entity) { 
    return await db.UpdateAsync(entity);
}

方法2:直接执行原生SQL语句(性能最优)

跳过实体操作,直接编写Update语句指定要更新的字段和条件,避免额外的查询开销:

// 新增一个针对性的更新方法
public async Task<int> UpdateDefaultUser(int pid, string defaultUserValue)
{
    string updateSql = "UPDATE Auth SET defaultUser = ? WHERE pid = ?";
    return await db.ExecuteAsync(updateSql, defaultUserValue, pid);
}

// 调用方式
await validateToken.UpdateDefaultUser(defaultUser.pid, "N");

方法3:通过反射自动忽略Null属性(自动化处理)

如果想保留你原来的实体传入方式,可以写一个工具方法,自动将传入实体中Null的属性替换为数据库中现有实体的对应值:

// 扩展方法,用于合并现有实体和更新实体的属性
public static async Task<T> MergeWithExistingAsync<T>(this SQLiteAsyncConnection db, T updatedEntity) where T : class, new()
{
    // 这里假设实体的主键是pid,需根据你的实际主键调整
    var primaryKeyProp = typeof(T).GetProperty("pid");
    if (primaryKeyProp == null)
        throw new InvalidOperationException("实体未找到主键属性pid");

    var primaryKeyValue = primaryKeyProp.GetValue(updatedEntity);
    var existingEntity = await db.FindAsync<T>(primaryKeyValue);

    // 遍历所有属性,将更新实体中为Null的属性替换为现有实体的值
    foreach (var prop in typeof(T).GetProperties())
    {
        var updatedValue = prop.GetValue(updatedEntity);
        if (updatedValue == null)
        {
            prop.SetValue(updatedEntity, prop.GetValue(existingEntity));
        }
    }

    return updatedEntity;
}

// 调用方式
var updatedAuth = new Auth { pid = defaultUser.pid, defaultUser = "N" };
updatedAuth = await db.MergeWithExistingAsync(updatedAuth);
await validateToken.Update(updatedAuth);

各方法对比

  • 方法1:简单易维护,适合字段较少的场景,但需要额外一次数据库查询。
  • 方法2:性能最高,无额外查询,但需要手动编写SQL,缺乏类型安全。
  • 方法3:无需手动处理每个字段,自动化程度高,但反射会带来轻微性能损耗。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 16:22:41