【问题标题】:Generic Method to create Parameterized SQL from a Class从类创建参数化 SQL 的通用方法
【发布时间】:2014-10-24 17:46:07
【问题描述】:

我正在使用一个包含 200 多个表的数据库。我已经能够根据表结构自动生成类。我还可以通过这样的 foreach 循环使用数据表自动生成插入语句:

foreach (DataColumn col in table.Columns)
{
    colnames.Add("[" + col.ColumnName + "]");
}

但是我的目标是根据类本身的定义创建参数化 SQL 语句,而我正在画一个空白。

例如:

类声明:

public class clsCaseWorker
{
    public string CaseWorkerId{ get; set; }
    public string CaseWorkerFirstName{ get; set; }
    public string CaseWorkerLastName{ get; set; }
    public string CaseWorkerMiddleName{ get; set; }
    ...

应该像这样生成一个方法/参数化查询(注意类名将映射到表名)

public clsSavedInfo SaveCaseWorkerInfo(clsCaseWorker CaseWorker)
{
    string saveCaseWorker;
    saveCaseWorker = "insert into CaseWorker ";
    saveCaseWorker += "([CaseWorkerFirstName], [CaseWorkerLastName], ";
    saveCaseWorker += "[CaseWorkerMiddleName], ...";
    saveCaseWorker += "Values(@cw_FirstName, @cw_LastName, @cw_MiddleName, @cw_CellPhone, @cw_HomePhone, @cw_Address, @cw_Tribe, @cw_TribeName, ";
    saveCaseWorker += "@cw_District, @cw_Title19, @cw_Title19Address, @cw_StateProgram, @cw_StateProgramText) SELECT CaseWorkerID FROM CaseWorker WHERE CaseWorkerID = @@IDENTITY";

    SqlCommand cmd = new SqlCommand(saveCaseWorker, con);

    cmd.Parameters.AddWithValue("@cw_FirstName", CaseWorker.CaseWorkerFirstName);
    cmd.Parameters.AddWithValue("@cw_LastName", CaseWorker.CaseWorkerLastName);
    cmd.Parameters.AddWithValue("@cw_MiddleName", CaseWorker.CaseWorkerMiddleName);
    ...

任何为我指明正确方向的建议将不胜感激。

【问题讨论】:

  • 我认为你应该尝试Dapper 而不是重新发明轮子
  • 您的代码甚至无法编译,cmd.arameters 不是属性。
  • 为什么不直接使用EntityFramework
  • @Steve 他们可能无法在他们的系统中使用外部库。虽然强烈推荐,但并非适用于所有情况。
  • “如果你手工编写 ADO.Net 代码,你就是在偷你的雇主或客户的东西” - Jeremy Miller

标签: c# sql sql-server linq oop


【解决方案1】:

但是我的目标是根据类本身的定义创建参数化 SQL 语句,而我正在画一个空白。

看起来开始应该是使用Reflection。一旦你有了类属性/值,我相信你可以处理剩下的。

public class MyClass
{
  public int PropertyName { get; set; }   
}

使用反射:

public static List<string> GetPropertyNames<T>()
{
    string result = null;

    var tableType = typeof(T);
    var result = tableType.GetProperties(BindingFlags.GetProperty 
                                         | BindingFlags.Instance 
                                         | BindingFlags.Public)
      .Select(p => p.Name)
      .ToList();

    return result;
}

public static object GetValue(object classInstance, string propertyName)
{
  var tableType = classInstance.GetType();
  var prop = tableType.GetProperty(propertyName);
  var result = prop.GetValue(classInstance);

  return result;
}

例如:

public class MyClass
{
  public int PropertyName { get; set; }   
}

var result = GetPropertyNames<MyClass>();
Console.WriteLine(result.First());

结果:

属性名称

(我还要提到我没有在我的方法中检查任何空参数)

此外,.Net 框架中已经有相当多的ORMs 可以执行您正在执行的操作。我强烈建议您在当前的行动过程中使用其中任何一种(如果没有商业理由不这样做)。

【讨论】:

    猜你喜欢
    • 2013-04-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-15
    • 1970-01-01
    • 2011-11-25
    • 1970-01-01
    • 2022-10-23
    • 1970-01-01
    相关资源
    最近更新 更多