如何以正确的方式使用EF保存数据(多个表)

时间:2019-05-15 16:02:54

标签: c# entity-framework

例如,您有两个表,这些表通过ICollection属性连接(先编码)。

public class EntityEnviroment
{
    [Key]
    public virtual int env_id { get; set; }

    public virtual string env_name { get; set; }

    public virtual string env_country { get; set; }

    public virtual ICollection<StcEntityFailedReportDetail> failedReportDetails { get; set; }
}

public class EntityFailedReportDetail
{
    [Key]
    public virtual int failed_reports_details_id { get; set; }

    public virtual int report_id { get; set; }

    public virtual string report_status { get; set; }

    public virtual StcEntityEnviromentStatus StcEntityEnviromentStatus { get; set; }
}

对于一个表,我创建了上下文的一个实例,并为我的条目创建了一个实例,然后将其添加。最后,我保存了它。对于多个表,我这样做:

        using (var db = new StatusPlatformContext())
        {
            var entryDetail = new EntityFailedReportDetail();
            foreach (var value in result.failed_report_details)
            {

                entryDetail.report_id = value.report_id;
                entryDetail.report_status = value.report_status;

                db.StcEntityFailedReportDetails.Add(entryDetail);

            }

            var entry = new EntityEnviroment
            {
                env_name = result.environment_status.env_name,
                env_country = "Ger",
                failedReportDetails = new List<EntityFailedReportDetail> { entryDetail }
            };
            entryDetail.EntityEnviroment = entry;
            db.EntityEnviromentStat.Add(entry);
            db.SaveChanges();
        }

如果我这样做,将仅保存详细信息的最后一个条目。如果将db.SaveChanges()添加到foreach中,我只会在前三个字段的最后一行的前生密钥列中得到一个条目。

我应该如何构建代码?我发现的所有示例仅显示一个表不是多个。有没有带模式的示例我应该阅读?

谢谢

2 个答案:

答案 0 :(得分:0)

有两个问题

1)您需要为每个结果创建一个新的EntityFailedReportDetail。

2)另外,在制作完每个EntityFailedReportDetail之后,将它们添加到EntityEnvironment。

尝试一下:

result = pd.merge(df, NRSRO, how = 'inner', on = ['Date', 'Counterparty'])

答案 1 :(得分:0)

对于包含其他实体集合的实体,应在构造时初始化这些集合:

public class EntityEnviroment
{
    [Key]
    public virtual int env_id { get; set; }
    public virtual string env_name { get; set; }
    public virtual string env_country { get; set; }
    public virtual ICollection<StcEntityFailedReportDetail> failedReportDetails { get; set; } = new List<StcEntityFailedReportDetail>();
}

这样,您可以立即在新实体上使用这些集合。在代码中“设置”集合的任何地方都应标记为进行调查。例如,这不是从数据库中清除集合的方法,因此,如果除此(或构造函数)之外的其他任何地方执行= new List<TEntity>()都是问题。

var entryDetail = new EntityFailedReportDetail();
foreach (var value in result.failed_report_details)
{
    entryDetail.report_id = value.report_id;
    entryDetail.report_status = value.report_status;
    db.StcEntityFailedReportDetails.Add(entryDetail);
}

此代码的问题是,您要初始化1条“详细”记录,然后循环执行,更新其详细信息,然后尝试将其“添加”到DbSet中。这是一个参考。

然后输入此代码:

failedReportDetails = new List<EntityFailedReportDetail> { entryDetail }

只需使用您添加的最新详细信息对该引用进行初始化即可。

调整示例:

using (var db = new StatusPlatformContext())
{
    var entry = new EntityEnviroment
    {
        env_name = result.environment_status.env_name,
        env_country = "Ger",
    };

    foreach (var value in result.failed_report_details)
    {
        var entryDetail = new EntityFailedReportDetail
        {
            report_id = value.report_id,
            report_status = value.report_status,
            EntityEnvironment = entry
        };
        entry.failedReportDetails.Add(entryDetail);
    }

    db.EntityEnviromentStat.Add(entry);
    db.SaveChanges();
}

您不需要显式地将每个详细信息添加到上下文的DbSet详细信息中,并且如果您不需要查询条目外部的详细信息,则您的上下文甚至不需要DbSet of details。 EF将管理相关的实体,因此您仅需要“顶层”实体的DbSet,基本上就是系统分别引用的父实体。您始终可以通过其父实体查询相关实体。