在Linq2DB中基于可选值实现IUpdatable<T>与IValueInsertable<T>是否可行
问题核心原因
ITable<T>调用Set()扩展方法后返回的类型是IUpdatable<T>,调用Value()方法后返回的是IValueInsertable<T>,二者和ITable<T>没有类型兼容关系,你用ITable<T>类型的变量接收方法返回值自然会报类型不匹配错误,这是Linq2DB类型体系设计的正常结果,不是你的实现思路有问题。
更新场景正确实现
只需将存储中间结果的变量类型改为IUpdatable<T>即可:
var optional1 = Optional<int>.None(); var optional2 = Optional<int>.Of(123); // 初始构造IUpdatable类型对象 IUpdatable<MyRecord> updater = Database.MyTable; if (optional1.HasValue) updater = updater.Set(x => x.Optional1, optional1.Value); if (optional2.HasValue) updater = updater.Set(x => x.Optional2, optional2.Value); await updater.UpdateAsync();
*注意:上述示例没有加过滤条件,执行后会更新整张表的对应字段,实际使用时需要先通过Where()方法指定要更新的行范围再调用Set()。
插入场景正确实现
同理将变量类型声明为IValueInsertable<T>即可:
var optional1 = Optional<int>.None(); var optional2 = Optional<int>.Of(123); // 初始构造IValueInsertable类型对象,非空必填字段可提前赋值 IValueInsertable<MyRecord> inserter = Database.MyTable.Value(x => x.RequiredField, "固定必填值"); if (optional1.HasValue) inserter = inserter.Value(x => x.Optional1, optional1.Value); if (optional2.HasValue) inserter = inserter.Value(x => x.Optional2, optional2.Value); await inserter.InsertAsync();
最佳实践说明
- 动态拼接更新/插入字段是Linq2DB支持的标准用法,符合框架设计预期,不属于不合理的实现思路。
- 链式调用过程中不要复用
ITable<T>类型变量存储中间构造结果,按照操作类型分别用IUpdatable<T>、IValueInsertable<T>、IQueryable<T>存储对应阶段的构造对象即可。 - 如果多场景复用同一份条件赋值逻辑,可以把逻辑封装成针对
IUpdatable<T>/IValueInsertable<T>的扩展方法,减少重复代码。
内容的提问来源于stack exchange,提问作者mihails.kuzmins
相关产品推荐
相关产品推荐

