C#类库SQL插入选择自

本文关键字:选择 插入 SQL 类库 | 更新日期: 2023-09-27 18:22:11

我正在尝试编写一个C#类,该类将允许我在SQL中将数据从Live表审计到audit表。显示对数据所做更改的完整历史记录。

INSERT INTO tbl_audit SELECT * FROM tbl_data WHERE ID = id

如果我的类库中的两个表列匹配,那么我就可以使用它了,我真正需要做的是能够定义列:

INSERT INTO tbl_audit (cols) SELECT (vars) FROM tbl_data WHERE ID = id

有人能解释一下我如何循环通过所需变量的每个列吗?这可能吗?所以它看起来像:

INSERT INTO tlb_audit (col1, col2, col3) SELECT (col1, col2, col3) FROM tbl_data WHERE ID = id

我的代码看起来像:

class.connection = myconnection.cs
class.currenttable = "tbl_data"
class.newtable = "tbl_audit"
class.col("sqlColumn1_in_tbl_audit")
class.col("sqlColumn1_in_tbl_data")
class.col("sqlColumn2_in_tbl_audit")
class.col("sqlColumn2_in_tbl_data")
etc
class.commit

C#类库SQL插入选择自

您可以使用这样的脚本来获取表列名:

SELECT COLUMN_NAME 
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'YourTableName' AND TABLE_SCHEMA='YourSchemaName'

一旦得到结果,就可以遍历名称来构建INSERT查询。不过,我不确定这会给你带来什么样的审计。我认为您最好使用DBMS构建该功能,也许可以使用触发器

以下是我对我们的一个应用程序中已审核表的电子邮件通知所做的操作。它从EntityFramework的数据上下文中读取实体状态,并将更改格式化为格式化的json字符串。

public override int SaveChanges()
{
    var auditChanges = ChangeTracker.Entries()
            .Where(t => t.State != EntityState.Unchanged && t.Entity.GetType().IsDefined(typeof(AuditAttribute),true))
            .Select(t =>
            {
                var entityType = t.Entity.GetType();
                if (entityType.BaseType != null && entityType.Namespace == "System.Data.Entity.DynamicProxies")
                {
                    entityType = entityType.BaseType;
                }
                return new
                {
                    entityType.Name,
                    State = t.State.ToString(),
                    Changes = t.State == EntityState.Deleted ? null : t.CurrentValues.PropertyNames
                        .Where(pn => t.State == EntityState.Added || t.CurrentValues[pn] == null && t.OriginalValues[pn] != null || t.CurrentValues[pn] != null && !(t.CurrentValues[pn].Equals(t.OriginalValues[pn])))
                        .ToDictionary(pn => pn, pn => t.CurrentValues[pn]),
                    Original = t.State == EntityState.Added ? null :
                        t.OriginalValues.PropertyNames.ToDictionary(pn => pn,
                            pn => t.OriginalValues[pn])
                };
            });
    if (auditChanges.Any())
    {
        var auditMessage = new StringBuilder(2048);
        var changes = JsonConvert.SerializeObject(auditChanges, Formatting.Indented);
        auditMessage.AppendFormat("Timestamp: {0}'r'nUser: {1}'r'nIP Address: {2}'r'n===================='r'n{3}'r'n",
            DateTime.Now, HttpContext.Current == null || HttpContext.Current.User == null ? "" : HttpContext.Current.User.Identity.Name,
        Controllers.BaseController.GetIpAddress(HttpContext.Current),changes);
    NotificationManager.SendNotifications(NotificationType.Audit, this, GetDataSession(),null,auditMessage.ToString());
    }
    retval = base.SaveChanges();
}

我使用以下审核属性标记要审核的类:

public class AuditAttribute : Attribute { }

像这样:

[Audit]
public partial class Agency { }

如果不使用框架,则需要一种方法来识别表行的前后快照,以便构建类似的内容。您还可以将审核日志存储到数据库中,或者使用syslog样式的日志api。

Sample Audit Table:
Timestamp Date,
EntityName varchar2(50),
Changes varchar2(MAX)?

以下是当有人更改跟踪表时我们收到的示例电子邮件:

The following database changes were made to tracked objects:
Timestamp: 11/13/2015 2:02:34 PM
User: 
IP Address: 173.165.34.65
====================
[
 {
   "Name": "CarrierSetting",
   "State": "Modified",
   "Changes": {
     "DirectBill": true
   },
   "Original": {
     "Id": 531,
     "CarrierCode": "MEXIC",
     "AllowQuote": true,
     "AllowBOL": true,
     "DirectBill": false,
     "RequireDocusign": false,
   }
 }
]

这样做的好处是,理论上可以在更改时通过反序列化Json字符串来重建数据库。