【问题标题】:Parameterized query - multi objects参数化查询 - 多对象
【发布时间】:2022-01-18 22:17:38
【问题描述】:

我发现question 这正是我想要做的。正确的答案似乎正是我想要的,但我想做一些事情,不要再次输入所有参数。

我有一个<Repere>,我已经为一个简单的参数化查询实现了一个函数:

public MySqlParameter[] GetListMySqlParams()
{
    return this.getListMySqlParams();
}
private MySqlParameter[] getListMySqlParams()
{
    MySqlParameter[] listParams = new MySqlParameter[]
    {
        new MySqlParameter("idContract", this.contrat.ID),
        new MySqlParameter("contractCode", this.Contrat.Code),
        new MySqlParameter("phaseName", this.fase.Name),
        new MySqlParameter("assemblyName", this.assembly.Name),
        new MySqlParameter("idPhase", this.fase.ID),
        new MySqlParameter("idAss", this.assembly.ID),
        new MySqlParameter("name", this.name),
        new MySqlParameter("priority", this.priority),
        new MySqlParameter("quantity", this.quantity),
        new MySqlParameter("totalQuantity", this.totalQuantity),
        new MySqlParameter("listOperations", this.listOperations.ConvertToString()),
        new MySqlParameter("material", this.geometry.Material),
        new MySqlParameter("drawing", this.geometry.Drawing),
        new MySqlParameter("profile", this.geometry.Profile.Name),
        new MySqlParameter("groupeProfil", this.geometry.GroupeProfil),
        new MySqlParameter("length", this.geometry.Length),
        new MySqlParameter("weightNet", this.geometry.WeightNet),
        new MySqlParameter("revision", this.geometry.Revision),
        new MySqlParameter("principal", this.principal),
        new MySqlParameter("unloadingZone", this.unloadingZone),
        new MySqlParameter("executionClass", this.executionClass),
        new MySqlParameter("category", this.category.ID),
        new MySqlParameter("description", this.description),
        new MySqlParameter("workingOrder", this.workingOrder),
        new MySqlParameter("isMountingPart", this.isMountingPart),
        new MySqlParameter("isPRS", this.isPRS),
        new MySqlParameter("idPRS", this.idPRS),
        new MySqlParameter("importOk",this.geometry.ImportOk),
    };
    return listParams;
}

我想要在那里使用解决方案,但不必再次输入所有参数(因为我想在几个对象和很多参数上这样做)。

这是我现在拥有的:

private void insertListReperes(List<Repere> listReperes)
{
    if (this.OpenConnection() == true)
    {
        using (this.connection)
        {
            string query = "INSERT INTO [vsteel].detail (ID_CONTRACT,NAME_CONTRACT,NAME_PHASE,NAME_ASS,ID_PHASE,ID_ASS,NAME,NAME_ORI,PRIORITY,QTE,QTE_TOT,OP," +
            "MATERIAL,DRAWING,PROFILE,GROUP_PROFILE,LENGTH,WEIGHT,REVISION,PRINCIPAL,UNLOADING_ZONE,EXECUTION_CLASS,ID_CATEGORY,DESCRIPTION,WORKING_ORDER," +
            "IS_MOUNTING_PART,IS_PRS,ID_PRS,IMPORT_OK) " +
            "VALUES (@idContract,@contractCode,@phaseName,@assemblyName,@idPhase,@idAss,@name,@name,@priority,@quantity,@totalQuantity,@listOperations," +
            "@material,@drawing,@profile,@groupeProfil,@length,@weightNet,@revision,@principal,@unloadingZone,@executionClass,@category,@description,@workingOrder," +
            "@isMountingPart,@isPRS,@idPRS,@importOk)";
            using (MySqlCommand cmd = new MySqlCommand(query.Replace("[vsteel].", ""), connection))
            {
                for(int i=0;i<listReperes.Count();i++)
                {
                    Repere repere = listReperes[i];
                    if(i==0)
                    {
                        MySqlParameter[] listParams = repere.GetListMySqlParams();
                        for (int j = 0; j < listParams.Count(); j++)
                        {
                            cmd.Parameters.Add(listParams[i]);
                        }
                        cmd.Prepare();
                        cmd.ExecuteNonQuery();
                    }
                    else
                    {
                        MySqlParameter[] listParams = repere.GetListMySqlParams();
                        for (int j = 0; j < listParams.Count(); j++)
                        {
                            cmd.Parameters[listParams[i].ParameterName].Value = listParams[i].Value;
                        }
                        cmd.ExecuteNonQuery();
                    }
                    repere.ID = cmd.LastInsertedId;
                }
            }
        }
    }
}

但是当我尝试在cmd.Parameters[listParams[i].ParameterName].Value = listParams[i].Value; 行设置参数时,它给了我参数已经定义的错误。 有没有办法在不复制所有参数名称的情况下做到这一点?

【问题讨论】:

  • 只需 Clear()ing 参数集合,然后使用 AddRange(listParams) 添加所有新参数怎么样?
  • 顺便说一句,如果你使用 Dapper,你的整个 insertListReperes 代码将减少到 connection.Execute(query, repere) 加上设置查询和连接的行 - 你甚至不需要 getListMySqlParams 方法; Dapper 会做到这一点 - 只需向它提供一个充满 @parameterNames 的 SQL,与你的属性名称匹配(你似乎有这个)并在参数参数中传递一个 Repere 实例
  • 我建议不要单独使用大小写来区分方法名称。也建议不要使用 camelCase 作为属性;请使用 PascalCase
  • 我每次都需要准备 - 我不这么认为 - dev.mysql.com/doc/connector-net/en/… 在调用 prepare 后创建参数
  • PascalCaseStartsWithAnUpper,而 camelCaseStartsWithALower - 通常我们在 C# 中用 PascalCase 命名公共事物,用 camelCase 命名本地或私有事物(类字段)。仅区分大小写;这不是很明显,而且 CLR 中的某些语言不支持大小写。例如,使用具有两个仅在大小写上不同的 pub 方法的 C# DLL 会导致 VB 出现问题。我很欣赏您的方法是私有的,因此只有您会被它们混淆,但是“仅案例”方法可能会很好是一个等待发生的堆栈溢出错误。

标签: c# mysql prepared-statement


【解决方案1】:

所以,我发现了问题。错误没有被抛出你所说的那一行;它在cmd.Parameters.Add 行上,这更有意义(源代码只会在添加期间抛出“已经存在”)

你写过:

cmd.Parameters.Add(listParams[i]);

你应该写:

cmd.Parameters.Add(listParams[j]);

通过使用[i],您可以重复添加idContact 的参数,因为ij 循环的每次传递中始终为0


请注意,您在下一行也犯了同样的错误,因此您将 idContact 的值重复设置了 21 次


顺便说一句,我提到了一个名为 Dapper 的库(stackoverflow 将它用于所有数据访问),它可以让您的生活变得更简单。如果你写这样的代码:

using var connection = ... //get your connection here
var sql = "INSERT ... VALUES(@parameter, @names, @identical, @to, @your, @object, @properties); SELECT LAST_INSERT_IDENTITY()";
foreach(var v in itemstoinsert)
  v.id = connection.ExecuteScalar<int>(sql, v);

它应该是你所需要的一切......

【讨论】:

  • 是的,你是对的,对不起。然后我终于决定每次都按照你的建议做(clear(),AddRange()。代码比我的更清晰,所以除非它可以赚取时间,我认为它更好。谢谢
  • 没问题。我还添加了一些关于 Dapper 以及它如何让生活变得更轻松的信息!
猜你喜欢
  • 1970-01-01
  • 2019-07-27
  • 1970-01-01
  • 2017-11-14
  • 2015-01-10
  • 2017-08-31
相关资源
最近更新 更多