Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在ASP.Net内核中使用历史表存储历史数据_C#_Asp.net Core_Database Design_Asp.net Core Webapi_Historical Db - Fatal编程技术网

C# 在ASP.Net内核中使用历史表存储历史数据

C# 在ASP.Net内核中使用历史表存储历史数据,c#,asp.net-core,database-design,asp.net-core-webapi,historical-db,C#,Asp.net Core,Database Design,Asp.net Core Webapi,Historical Db,我的数据库中有一个实体与多个实体链接,我需要在基本实体中存储更改(更新和删除)的历史数据。现在我们采用的方法是将每个数据保存在相应的历史实体中。基本表如下所示: public partial class Con { public Guid Id { get; set; } public DateTime? DateCreated { get; set; } public DateTime? DateModified { get; set; } public bo

我的数据库中有一个实体与多个实体链接,我需要在基本实体中存储更改(更新和删除)的历史数据。现在我们采用的方法是将每个数据保存在相应的历史实体中。基本表如下所示:

public partial class Con 
{
    public Guid Id { get; set; }
    public DateTime? DateCreated { get; set; }
    public DateTime? DateModified { get; set; }
    public bool? Deleted { get; set; }
    public string Status { get; set; }
    public string Reference { get; set; }
    public string Note { get; set; }
    public int? TotalPieces { get; set; }
    public decimal? TotalVolume { get; set; }
    public decimal? TotalWeight { get; set; }
    public virtual ICollection<Document> Document { get; set; }
    public virtual ICollection<ConLine> ConLine { get; set; }
    public virtual ICollection<Leg> Leg { get; set; }
}
公共部分类Con
{
公共Guid Id{get;set;}
公共日期时间?DateCreated{get;set;}
公共日期时间?日期修改{get;set;}
公共bool?已删除{get;set;}
公共字符串状态{get;set;}
公共字符串引用{get;set;}
公共字符串注释{get;set;}
公共int?TotalPieces{get;set;}
公共十进制?总卷{get;set;}
公共十进制?总权重{get;set;}
公共虚拟ICollection文档{get;set;}
公共虚拟ICollection ConLine{get;set;}
公共虚拟ICollection分支{get;set;}
}
历史表是这样的,我不确定如何设计历史表来保存链接表数据

public partial class ConHistory 
{
    public Guid Id { get; set; }
    public Guid ConId { get; set; }
    public int TransactionId { get; set; }
    public Guid ModifiedByUser { get; set; }
    public DateTime Date { get; set; }
    public DateTime? DateCreated { get; set; }
    public DateTime? DateModified { get; set; }
    public bool? Deleted { get; set; }
    public string Status { get; set; }
    public string Reference { get; set; }
    public string Note { get; set; }
    public int? TotalPieces { get; set; }
    public decimal? TotalVolume { get; set; }
    public decimal? TotalWeight { get; set; }
    public virtual ICollection<Document> Document { get; set; }
    public virtual ICollection<ConLine> ConLine { get; set; }
    public virtual ICollection<Leg> Leg { get; set; }
}
公共部分类历史记录
{
公共Guid Id{get;set;}
公共Guid ConId{get;set;}
public int TransactionId{get;set;}
公共Guid ModifiedByUser{get;set;}
公共日期时间日期{get;set;}
公共日期时间?DateCreated{get;set;}
公共日期时间?日期修改{get;set;}
公共bool?已删除{get;set;}
公共字符串状态{get;set;}
公共字符串引用{get;set;}
公共字符串注释{get;set;}
公共int?TotalPieces{get;set;}
公共十进制?总卷{get;set;}
公共十进制?总权重{get;set;}
公共虚拟ICollection文档{get;set;}
公共虚拟ICollection ConLine{get;set;}
公共虚拟ICollection分支{get;set;}
}
我如何处理这个问题?最佳行业实践是什么?我主要关心的是收集数据。因为历史记录表没有与它们链接


任何一种建议都会大有帮助

对于简单的时间序列数据,使用可修改字段的副本保存单独的表是一种非常有效的方法。不幸的是,在您的情况下,您还需要制作每个链接表的副本,以便维护一致的外键,例如,
DocumentHistory
ConLineHistory
LegHistory
。这是很多重复的代码。然后你必须考虑,当模式改变时,所有历史记录发生了什么?

就我个人而言,我会将这些信息作为json存储在文本列中。您搜索的所有字段都应该是sql,这样您就可以对其进行索引,但其余字段可以序列化为json字符串:

public partial class ConHistory 
{
    public Guid Id { get; set; }
    public Guid ConId { get; set; }
    public int TransactionId { get; set; }
    public Guid ModifiedByUser { get; set; }
    public DateTime Date { get; set; }

    // Serialize the rest of the `ConHistory` fields to a json object, and store them here
    public string Json { get; set; }
}

Sql还具有
JSON\u VALUE
函数,如果您确实需要从JSON字符串中获取值以进行查询,则可以在实体框架中使用此函数。

感谢您的见解。我需要查询历史数据以便审计。每次运行查询时,是否必须将json数据转换为实际对象?或者还有其他方法吗?还有一件事所有这些数据:con、conline、文档、leg将在同一事务中发布。如果我们保留单独的历史记录表,您将如何处理这种情况?您可以创建一个自定义的来处理从json到强类型对象的转换。根据你的第二条评论,我不确定我是否理解这个问题,但我将尝试解决它。如果你决定将它们都保存在单独的历史记录表中,你可以选择:只需插入父对象,EF将遍历导航属性,并将子对象添加到相应的表中。或者:您可以将逻辑保存在数据库中的SQL插入触发器中。我不确定你说的是什么卷,但EntityFramework在插入复杂的文档时有点慢。它逐个插入各个实体,并等待id返回。对于小吞吐量,这是好的,对于大吞吐量则不是。