【问题标题】:Accessing a single field in a foreach using Linq Dapper使用 Linq Dapper 访问 foreach 中的单个字段
【发布时间】:2019-05-26 19:28:34
【问题描述】:

我正在使用 dapper,我想使用 Linq 来更新我正在尝试使用的一个表中名为 status 的单个字段。

public async Task<Int32> ProcessUnprocessedTransactions(IEnumerable<BomComponentData> items)
{
    IEnumerable<BomComponentData> _itemstoBeProcesed = items.Where(w => w.Status == (int)BomStatus.Scanned);

    foreach (BomComponentData item in _itemstoBeProcesed)
    {
        item.Status = (int)BomStatus.Completed;
    }            

    return await database.UpdateAsync(_itemstoBeProcesed);       
}

我的班级如下:

public class BomComponentData
{
    public int Sequence { get; set; }

    public string BOMShortName { get; set; }
    public string OperationName { get; set; }
    public long BomId { get; set; }
    public long BOMLineID { get; set; }
    public long StockItemID { get; set; }
    public string BomLineType { get; set; }
    public int Quantity { get; set; }
    public long UnitID { get; set; }
    public decimal? MultipleOfBaseUnit { get; set; }
    public string Code { get; set; }
    public string Name { get; set; }
    public string Barcode { get; set; }
    public long ProductGroupID { get; set; }
    public string ProductGroupCode { get; set; }
    public int Status { get; set; }

    public int BinLocation { get; set; }
    public string BinName { get; set; }

    public string UOM { get; set; }
    public int CalculatedValue { get; set; }
    public int BomPickedCount { get; set; }

    public int TotalLeftTopick
    {
        get { return Quantity - BomPickedCount; }         
    }

    public enum BomStatus
    {
        Listed=1,
        Scanned=2,
        Confirmed=3,
        Processed=4,
        Completed=4,
        InVisible=5
    }

    public override string ToString()
    {
        return Code; 
    }
}

但是,如果我使用上面的 foreach,它就不起作用。我确信它应该正确更新这些项目,但我认为因为我正在查看我的 foreach 中的单个项目以及更新中的列表,所以它没有正确更新。

我要做的就是将项目标记为已完成并准备好转移,我通过状态列和一个 int 枚举来这样做。

也许我错过了我的主键是什么的声明?

编辑 2

当我使用主键的键声明时,我得到以下信息:

未处理的异常:System.AggregateException:发生一个或多个错误。 (约束

编辑 3

我已经设置了我班级的密钥,但正如你所见,我的数据库上有自动增量,但它仍然崩溃。插入应该如何处理?

编辑 4

例如,我按如下方式插入数据库。这不应该工作吗?

List<BomComponentData> _bomList = new List<BomComponentData>();
_bomList.Add(new BomComponentData { Sequence = 1, Barcode = "0000000001498", BinLocation = 23, BinName = "A", BOMShortName = "GYNE-TXX", OperationName = "Example Product", Code = "TB9175CEA", Name = "Tiburon Peri/Gynae Pack-10", Quantity = 1, UOM = "Each" });


await database.InsertAllAsync(_bomList,true);

我已经为可以正常工作的更新放置了标签键,但是当我尝试使用该键进行插入时,它并没有说约束错误,但更新有效。有人不知道我如何解决 Dapper contrib 中的插入和更新问题。

【问题讨论】:

  • 您使用适当的属性 [Key] 来装饰类,或者为您的代码定义的主键使用 [ExplicitKey]。请注意,您使用的是 Dapper 扩展。请参阅此处了解信息:github.com/StackExchange/Dapper/tree/master/Dapper.Contrib
  • 这个场景似乎在尖叫“用纯 SQL 在数据库中做这一切”......通过网络获取所有内容只是为了将其发送回来,因为更新似乎很难做到,不是吗?
  • 我必须调用应用程序即时通讯是 wcf,它本质上是单线程的,所以我别无他法,只能在设备上执行,然后发送到 wcf。

标签: c# sqlite linq dapper dapper-contrib


【解决方案1】:

您正在使用Dapper.Contrib,此扩展要求您使用一些属性来装饰您的类,以帮助自动处理您的数据。

特别是对于 Update 方法,您需要定义 Table 属性和 Key 属性来识别主键

[Table ("BomComps")]
public class BomComponentData
{
   // [ExplictKey]
   [Key]
   public int Sequence { get; set; }
   ....

这里,例如,我添加了属性Table来设置数据库上可能的表名,但是如果物理表的名称与类的名称匹配,则可以省略属性。我还添加了 Key 属性来设置包含表主键的属性(因此可以使用适当的 WHERE 条件形成更新记录的语句)。

请注意,如果列的 Identity 属性设置为 yes,则应使用 Key 属性,如果没有,则使用 ExplicitKey 属性表示主密钥由您的代码定义。

【讨论】:

  • 请看我上面的编辑我正在使用 xamrian 表单并在应用密钥后得到一个异常。
  • 所以这段代码在移动设备上的移动应用程序中运行?您正在更新此设备上的数据库?你用的是什么数据库?在 Dapper.Contrib 文档中有一条关于 SQLite 与其本机更新方法冲突的警告
  • 感谢史蒂夫,是的,你是正确的 sql lite,对不起,我没有这样做。
  • 是否有解决方法,因为 dapper 的贡献是最好的,所以它是
  • 我的数据库表设置为自动增量,但仍然出现同样的情况。
【解决方案2】:

这实际上是我必须用以下内容装饰我的班级的问题 将其留在这里,以便其他人有问题我正在使用 pcl 库,但由于某种原因,dapper contribe 没有检测到必须声明为的关键元素跟随。

[SQLite.PrimaryKey, SQLite.AutoIncrement]
public class StockTransferArgs
{
    [SQLite.PrimaryKey, SQLite.AutoIncrement]
    public int StockTransferArgsId { get; set; }
    public long StockItemID { get; set; }

    public string Code { get; set; }

    public string OperationName { get; set; }
    public string Description { get; set; }
    public decimal Quantity { get; set; }
    public long SourceWarehouseID { get; set; }
    public string SourceBinName { get; set; }
    public long TargetWarehouseID { get; set; }
    public string TargetBinName { get; set; }
    public string Reference { get; set; }
    public string SecondReference { get; set; }
    public string BarCode { get; set; }
    public int Status { get; set; }
}

【讨论】:

    猜你喜欢
    • 2021-05-19
    • 1970-01-01
    • 2015-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多