简体   繁体   English

使用类生成 SQL 插入语句

[英]Generating SQL insert statement using classes

I have a query regarding generating SQL insert statement using c# classes.我有一个关于使用 c# 类生成 SQL 插入语句的查询。 So I have a class called students.所以我有一个叫学生的class。

There is a function which gets list of students and dump that in database.有一个 function 获取学生列表并将其转储到数据库中。

Student Model学生 Model

public class Student
{
    public string ID { get; set; } = ""; // DB column name is studentID
    public string Name { get; set; } = ""; // DB column name is studentName
    public string address { get; set; } // DB column name is studentAddress
}

Function to dump Data Function 转储数据

public async Task<Error> DumpStudentAsync()
{
    List<Student> students = new List<Student>();

    StringBuilder query = new StringBuilder();

    query = query.Append("INSERT INTO Student(studentID,studentName,studentAddress) VALUES");
    string columnList = "(@studentID{0},@studentName{0},@studentAddress{0})";

    for (int i = 0; i < students.Count; i++)
    {
        query.AppendFormat($"{columnList},", i);
    }
    query = query.Replace(',', ';', query.Length - 1, 1);

    SqlCommand cmd = new SqlCommand
    {
        CommandText = query.ToString(),
    };
    for (int i = 0; i < students.Count; i++)
    {
        cmd.Parameters.AddWithValue($"@studentID{i}", students[i].ID);
        cmd.Parameters.AddWithValue($"@studentName{i}", students[i].Name);
        cmd.Parameters.AddWithValue($"@studentAddress{i}", students[i].address);
    }

    SQLWrapper db = new SQLWrapper(_ctx, "", DSConfig.SQLConnectionKey);
    return await db.ExecuteStatementAsync(cmd, "");
}

So here I want to make this function generic in such a way that if I add a new field in my student object there should be no code change done in my function.所以在这里我想让这个 function 通用,这样如果我在我的学生 object 中添加一个新字段,我的 function 中应该没有代码更改。 I tried searching the answers but I didn't get anything.我试着搜索答案,但我什么也没得到。

Here firstly I'm appending the insert format in query where I have hard-coded.首先,我将插入格式附加到我硬编码的查询中。 Secondly I'm appending variables for command parameters on the basis of students count which is also hard-coded.其次,我根据学生数量为命令参数附加变量,这也是硬编码的。 Also the class properties and database columns names are different how can I make use of class properties as DB column names? class 属性和数据库列名称也不同,如何将 class 属性用作数据库列名称?

Can I do something like this?我可以做这样的事情吗?

StringBuilder studentQuery = new StringBuilder();
string columns = "";
// Add column list on the basis of students properties
foreach (var property in Student.Properties)
{
    columns += "property.ID,"; // It should be studentID
}

// Add variables on the basis of students count

// Add command parameters value on the basis of students count

FYI: I'm using ADO.NET code to perform DB activities not Entity framework.仅供参考:我使用 ADO.NET 代码来执行数据库活动而不是实体框架。

you have to use reflection or use an ORM of your choice.您必须使用反射或使用您选择的 ORM。

This is an example to generate an update statement.这是生成更新语句的示例。 you have to adjust it a bit, but you should get the idea.您必须对其进行一些调整,但您应该明白这一点。

private string GetInsert<T>(T myObj)
{
    StringBuilder sb = new StringBuilder();
    int ctr = 0;

    Type type = typeof(T);
    StringBuilder sbQry = new StringBuilder();
    System.Reflection.PropertyInfo[] propInfo = type.GetProperties();
    foreach (var pi in propInfo)
    {
        // now you have the value of one property of your object
        var propertyValue = pi.GetValue(myObj);

        if (sbQry.ToString() == string.Empty)
            sbQry.AppendFormat("INSERT INTO {0} ({1}", 
               type.Name.Replace("Entity", string.Empty), pi.Name);
        else
        {
            sbQry.AppendFormat(", {0}", pi.Name);
            sb.Append(",");
        }
        sb.Append("{" + ctr++ + "}");
    }

    if (sbQry.ToString() != string.Empty)
        sbQry.AppendFormat(") VALUES({0})", sb.ToString());

    return sbQry.ToString();
}

This kind of automatic is not easily done.这种自动是不容易做到的。 .NET is strongly typed. .NET 是强类型的。 Unless you go into stuff like reflection or dynamic code to do it.除非您将 go 变成反射或动态代码之类的东西来做到这一点。 And I would not advise it.我不会建议它。 Strong Typisation is your friend.强类型化是你的朋友。 Without it you end up in the JavaScript and PHP examples for this comic .没有它,您最终会出现在此漫画的 JavaScript 和 PHP 示例中。 Hint: JS does the wrong thing in both cases.提示:JS 在这两种情况下都会做错事。

For me at least, having to do some minor changes on the frontend for changes on the Database is acceptable work.至少对我来说,必须在前端对数据库进行一些小的更改是可以接受的工作。 If anything that is the smalest, least dangerous part of the whole process.如果有什么是整个过程中最小、最不危险的部分。 So I can only advise against trying this.所以我只能建议不要尝试这个。

However for databases and only databases, stuff like Entity Framework might be a good idea.然而,对于数据库和只有数据库,像实体框架这样的东西可能是一个好主意。 It can generate your classes from the Database.它可以从数据库生成您的类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM