簡體   English   中英

我該如何防止多次插入?

[英]How should I prevent multiple inserts here?

我在大約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;
    }
}

然后插入我循環一些數據並插入:

        using (var context = new FinancialRecordContext())
        {
            foreach (var t in data)
            {
                var tran = new Transaction
                {
                    Description = t.Description,
                    Value = t.Value,
                    TransDate = t.TransDate,
                    Bank = context.FindOrInsertBank(t.BankName)
                };
                context.Transactions.Add(tran);
            }
            context.SaveChanges();
        }

似乎FindOrInsertBank方法一直進入數據庫,而不是在本地查看它最近添加但未提交的銀行。 我怎么能/應該這樣做?

每次銀行插入后我應該保存SaveChanges嗎? 不是我想要做的事情我希望這是一次交易。

您可以嘗試查詢更改跟蹤器(這是內存中查詢,而不是數據庫查詢):

using (var context = new FinancialRecordContext())
{
    foreach (var t in data)
    {
        Bank bank = context.ChangeTracker.Entries()
            .Where(e => e.Entity is Bank && e.State != EntityState.Deleted)
            .Select(e => e.Entity as Bank)
            .SingleOrDefault(b => b.Name == t.BankName);

        if (bank == null)
            bank = context.FindOrInsertBank(t.BankName);

        var tran = new Transaction
        {
            Description = t.Description,
            Value = t.Value,
            TransDate = t.TransDate,
            Bank = bank
        };
        context.Transactions.Add(tran);
    }
    context.SaveChanges();
}

編輯

在這里使用更改跟蹤器可能對性能Bank.Name ,因為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();
}

嘗試一些建議:

1)首先檢查DbSet<Bank>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();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM