Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/11.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# 我应该如何防止在这里多次插入?_C#_Entity Framework - Fatal编程技术网

C# 我应该如何防止在这里多次插入?

C# 我应该如何防止在这里多次插入?,c#,entity-framework,C#,Entity Framework,我插入了大约6家银行的5000笔交易,但我在数据库中得到了5000行名称重复的银行行 public class Transaction { [Key] public int Id { get; set; } public DateTime TransDate { get; set; } public decimal Value { get; set; } public string Description { get; set; } public

我插入了大约6家银行的5000笔交易,但我在数据库中得到了5000行名称重复的银行行

public class Transaction
{
    [Key]
    public int Id { get; set; }
    public DateTime TransDate { get; set; }
    public decimal Value { get; set; }
    public string Description { get; set; }
    public Bank Bank { get; set; }
}

public class Bank
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
}

public class FinancialRecordContext : DbContext
{
    public FinancialRecordContext() : base("FinancialRecordDatabase") { }

    public DbSet<Transaction> Transactions { get; set; }

    public DbSet<Bank> Banks { get; set; }

    public Bank FindOrInsertBank(string bankName)
    {
        var bank = Banks.SingleOrDefault(b => b.Name == bankName);
        if (bank == null)
        {
            bank = new Bank { Name = bankName };
            Banks.Add(bank);
        }
        return bank;
    }
}
似乎
FindOrInsertBank
方法一直都在访问数据库,而不是本地查看最近添加的数据库,而不是提交的银行。我怎么能/应该这样做


每次银行插入后,我是否应
保存更改
?不是我真正想做的,我希望这是一个事务。

您可以尝试查询更改跟踪器(这是内存查询,不是数据库查询):

编辑

在这里使用更改跟踪器可能对性能有害,因为
Bank.Name
不是实体的键,我猜查询将是对条目的线性搜索。在这种情况下,使用手写词典可能是更好的解决方案:

using (var context = new FinancialRecordContext())
{
    var dict = new Dictionary<string, Bank>();
    foreach (var t in data)
    {
        Bank bank;
        if (!dict.TryGetValue(t.BankName, out bank))
        {
            bank = context.FindOrInsertBank(t.BankName);
            dict.Add(t.BankName, bank);
        }

        var tran = new Transaction
        {
            Description = t.Description,
            Value = t.Value,
            TransDate = t.TransDate,
            Bank = bank
        };
        context.Transactions.Add(tran);
    }
    context.SaveChanges();
}
使用(var context=new FinancialRecordContext())
{
var dict=新字典();
foreach(数据中的var t)
{
银行;
如果(!dict.TryGetValue(t.BankName,out bank))
{
bank=context.FindOrInsertBank(t.BankName);
dict.Add(t.BankName,bank);
}
var tran=新交易
{
描述=t.描述,
值=t.值,
TransDate=t.TransDate,
银行
};
context.Transactions.Add(tran);
}
SaveChanges();
}

有几点建议可以尝试:

1) 首先检查
DbSet
Local
集合

public Bank FindOrInsertBank(string bankName)
{
    var bank = Banks.Local.SingleOrDefault(b => b.Name == bankName);
    if (bank == null)
    {
        var bank = Banks.SingleOrDefault(b => b.Name == bankName);
        if (bank == null)
        {
            bank = new Bank { Name = bankName };
            Banks.Add(bank);
        }
    }
    return bank;
}
2) 每次更新后强制调用
DetectChanges()

context.Transactions.Add(tran);
context.ChangeTracker.DetectChanges();

啊,
Local
,比我的变更跟踪查询要好得多。我总是忘记这件事…谢谢,就像编辑中的优化一样。尝试了ChangeTracker,但没有效果,仍然有5000家银行,可能需要
context.ChangeTracker.DetectChanges()也?@weston:Hm,变更跟踪查询实际上应该是qujck的
Local
查询的详细版本。看不出查询可能有什么问题。无论如何,忘了它吧,使用
Local
显然更干净<不需要code>DetectChanges
,因为
DbSet.Add
仍将在内部调用它。在我看来,无论是
Local
还是
dict
代码片段都是一种选择。
public Bank FindOrInsertBank(string bankName)
{
    var bank = Banks.Local.SingleOrDefault(b => b.Name == bankName);
    if (bank == null)
    {
        var bank = Banks.SingleOrDefault(b => b.Name == bankName);
        if (bank == null)
        {
            bank = new Bank { Name = bankName };
            Banks.Add(bank);
        }
    }
    return bank;
}
context.Transactions.Add(tran);
context.ChangeTracker.DetectChanges();