【问题标题】:C# INSERT with INSTEAD OF INSERT TRIGGERC# 插入而不是插入触发器
【发布时间】:2016-04-20 12:55:45
【问题描述】:

我的数据库中有一个表Teacher

TABLE Teacher
      (
        ID             CHAR (7) NOT NULL ,
        name           VARCHAR (50) NOT NULL ,
        surname        VARCHAR (50) NOT NULL ,
        email          VARCHAR (50) NOT NULL ,
        phone          CHAR (13) NOT NULL
      )

在数据库中,我有一个 INSTEAD OF INSERT 触发器,它创建 ID 和来自姓氏和数字的电子邮件。当我插入 SQL Server 时,一切正常。我可以的

INSERT INTO Teacher(name, surname, phone) 
VALUES('John', 'Doe', '+111111111111')

我正在这个数据库上实现 ORM。

public static String SQL_INSERT = 
    "INSERT INTO \"Teacher\" VALUES (@ID, @name, @surname, @email, @phone)";

    public static int Insert(Teacher teacher, Database pDb = null)
    {
        Database db;
        if (pDb == null)
        {
            db = new Database();
            db.Connect();
        }
        else
        {
            db = (Database)pDb;
        }

        SqlCommand command = db.CreateCommand(SQL_INSERT);
        PrepareCommand(command, teacher);
        int ret = db.ExecuteNonQuery(command);

        if (pDb == null)
        {
            db.Close();
        }

        return ret;
    }

    private static void PrepareCommand(SqlCommand command, Teacher teacher)
    {
        command.Parameters.AddWithValue("@ID", teacher.ID);
        command.Parameters.AddWithValue("@name", teacher.Name);
        command.Parameters.AddWithValue("@surname", teacher.Surname);
        command.Parameters.AddWithValue("@email", teacher.Email);
        command.Parameters.AddWithValue("@phone", teacher.Phone);
    }

问题是当我尝试从 ORM 插入时。我必须这样做,因为它不允许我在没有所有必需属性的情况下插入。

Teacher newTeacher  = new Teacher ();

newTeacher.ID = "";
newTeacher.Name= "John";
newTeacher.Surname= "Doe";
newTeacher.Email = "";
newTeacher.Phone= "+111111111111";

TeacherTable.Insert(newTeacher, db);

有什么方法可以插入而不需要将空字符串分配给 ID 和电子邮件? it inserts fine,但代码对我来说看起来很糟糕。感谢您的帮助。

【问题讨论】:

  • ID的内容是什么?
  • 你的 SQL_INSERT 字符串强迫你提供所有参数,你应该动态地为查询建立参数。
  • 您有什么理由要创建自己的本土 ORM?其中许多问题已经被实体框架或 NHibernate 等 ORM 解决了。为什么不选择现成的东西,以免浪费时间复制已经存在的东西?
  • "在数据库中,我有一个 INSTEAD OF INSERT 触发器,它根据姓氏和数字创建 IDemail。"他没有为这些值存储空值或空白。
  • @fqhv - 我错过了,谢谢。

标签: c# sql sql-server tsql


【解决方案1】:

如果您使用默认约束定义表,则值会在插入时设置为默认值,而无需触发器...

CREATE TABLE Teacher
(
    ID             CHAR (7) NOT NULL, --don't know what is the content here... In most cases an ID column with INT IDENTITY is perefered
    name           VARCHAR (50) NOT NULL CONSTRAINT DF_Teacher_name    DEFAULT(''),
    surname        VARCHAR (50) NOT NULL CONSTRAINT DF_Teacher_surname DEFAULT('') ,
    email          VARCHAR (50) NOT NULL CONSTRAINT DF_Teacher_email   DEFAULT('') ,
    phone          CHAR (13) NOT NULL    CONSTRAINT DF_Teacher_phone   DEFAULT('')
);

顺便说一句:我不会强制电话号码包含 13 个字符...

【讨论】:

  • 同意电话号码的评论,我们不能忘记国际号码!
  • @DavidC 我同意你的回答,赞成票是我的:-)
【解决方案2】:

ORM 正在做它应该做的事情。如果您的表字段可以为空,并且您的变量是未设置的引用类型,那么它应该插入一个 NULL。顺便说一句,字符串是引用类型。

处理此问题的最简洁方法之一是将构造函数添加到教师类,为所有值设置默认值,这样您就不必在每次新建对象时都设置它们。

例如

public class Teacher
{
    public Teacher()
      {
           ID = "";
           Name= "";
           Surname= "";
           Email = "";
           Phone= "";
      }
    ....
}

然后您可以执行以下操作:

Teacher newTeacher  = new Teacher ();
newTeacher.Name = "Johnny";
TeacherTable.Insert(newTeacher, db);

只设置你需要的变量,其他的都是构造函数中的默认设置。

【讨论】:

    【解决方案3】:

    您可以让 PrepareCommand 将它们默认为空白。

    private static void PrepareCommand(SqlCommand command, Teacher teacher)
    {
         command.Parameters.AddWithValue("@ID", teacher.ID ?? "");
         command.Parameters.AddWithValue("@name", teacher.Name);
         command.Parameters.AddWithValue("@surname", teacher.Surname);
         command.Parameters.AddWithValue("@email", teacher.Email ?? "");
         command.Parameters.AddWithValue("@phone", teacher.Phone);
     }
    

    或者,如果它们为空,则根本无法传递它们,然后在触发器中提供默认值。

    private static void PrepareCommand(SqlCommand command, Teacher teacher)
    {
        if(string.IsNullOrEmpty(teacher.ID))
            command.Parameters.AddWithValue("@ID", teacher.ID);
        command.Parameters.AddWithValue("@name", teacher.Name);
        command.Parameters.AddWithValue("@surname", teacher.Surname);
        if(string.IsNullOrEmpty(teacher.Email))        
            command.Parameters.AddWithValue("@email", teacher.Email);
        command.Parameters.AddWithValue("@phone", teacher.Phone);
    }
    

    这两种方法都允许您创建教师对象...

    Teacher newTeacher  = new Teacher ();
    
    newTeacher.Name= "John";
    newTeacher.Surname= "Doe";
    newTeacher.Phone= "+111111111111";
    
    TeacherTable.Insert(newTeacher, db);
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-21
    • 2019-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多