简体   繁体   English

C#类库SQL插入选择

[英]C# Class Library SQL Insert Into Select From

I'm trying to write a C# Class that will allow me to audit off data from a Live table to an Audit table in SQL. 我正在尝试编写一个C#类,该类将允许我将数据从Live表审核到SQL中的Audit表。 Showing a complete history of changes made to the data. 显示对数据所做更改的完整历史记录。

INSERT INTO tbl_audit SELECT * FROM tbl_data WHERE ID = id

I've got that one working ok if the two tables columns match ok in my Class Library, what I really need to do is able to define columns: 如果两个表的列在我的类库中匹配,我就可以正常工作了,我真正需要做的就是定义列:

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

Can someone explain how i can loop through each col passing through the required variable? 有人可以解释我如何遍历每个通过必需变量的col吗? Is it even possible? 可能吗? So it would look like: 因此,它看起来像:

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

my code would look something like: 我的代码如下所示:

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

You can use a script like this to get the table column names: 您可以使用如下脚本来获取表列名称:

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

Once you get back the result you can loop through the names to build your INSERT query. 获得结果后,您可以遍历名称以构建INSERT查询。 I'm not sure how this gives you auditing on the table though. 我不确定这如何使您在表上进行审核。 I think you might be better off building that functionality using the DBMS, maybe using Triggers 我认为您最好使用DBMS构建该功能,也许使用触发器

Here is what I do to email notifications for audited tables in one of our applications. 这是我通过电子邮件发送有关我们应用程序之一中已审核表的通知的操作。 It reads the entity state from EntityFramework's data context and formats the changes as a formatted json string. 它从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();
}

I tag classes to be audited with this audit attribute: 我使用以下审计属性标记要审计的类:

public class AuditAttribute : Attribute { }

Like so: 像这样:

[Audit]
public partial class Agency { }

If not using a framework, you'll need a way of identifying before and after snapshots of your table rows in order to build something similar. 如果不使用框架,则需要一种方法来标识表行快照之前和之后的快照,以便构建类似的内容。 You could also store your audit log into the database or using a syslog style logging api. 您还可以将审核日志存储到数据库中,或使用syslog样式的日志记录api。

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

Here is a sample email that we get when someone changes a tracked table: 这是当有人更改跟踪表时收到的电子邮件示例:

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,
   }
 }
]

The nice thing about this is that you could theoretically reconstruct the database at the time of the change by deserializing the Json strings. 这样做的好处是,理论上您可以在更改时通过反序列化Json字符串来重建数据库。

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

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