0

次のコード例を見てください。

機能:

  1. 多数の顧客を反復します。顧客がすでにわかっている場合は、その顧客の既存のデータベース オブジェクトを取得します (これが問題の多い部分です)。それ以外の場合は、新しいオブジェクトを作成します (これは正常に機能します)。
  2. 社会保障番号 (CPR) が一致するすべてのローンは、新規または既存の顧客に追加されます。

問題: 新しい顧客オブジェクトには機能しますが、既存の顧客オブジェクトを取得すると、ローンは保存時に顧客との関係を失います (CustomerID = null)。それらは引き続きデータベースに保存されます。

何か案は?

protected void BuildCustomerData()
{
    Console.WriteLine("  Starting the customer build.");

    var counter = 0;
    var recycleCount = 100;
    var reportingCount = 100;

    var sTime = DateTime.Now;

    var q = from c in db.IntermediaryRkos
            select c.CPR;

    var distincts = q.Distinct().ToArray();
    var numbersToProcess = distincts.Count();

    Console.WriteLine("  Identified " + numbersToProcess + " customers. " + (DateTime.Now - sTime).TotalSeconds);

    foreach (var item in distincts)
    {
        var loans = from c in db.IntermediaryRkos
                    where c.CPR == item
                    select c;

        var existing = db.Customers.Where(x => x.CPR == item).FirstOrDefault();

        if (existing != null)
        {
            this.GenerateLoanListFor(existing, loans);
            db.Entry(existing).State = System.Data.EntityState.Modified;
        }
        else
        {
            var customer = new Customer
            {
                CPR = item,
            };

            this.GenerateLoanListFor(customer, loans);
            db.Customers.Add(customer);
            db.Entry(customer).State = System.Data.EntityState.Added;
        }

        counter++;

        if (counter % recycleCount == 0)
        {
            this.SaveAndRecycleContext();
        }

        if (counter % reportingCount == 0)
        {
            Console.WriteLine("    Processed " + counter + " customers of " + numbersToProcess + ".");
        }
    }

    db.SaveChanges();
}

protected void GenerateLoanListFor(Customer customer, IQueryable<IntermediaryRko> loans)
{
    customer.Loans = new List<Loan>();

    foreach (var item in loans.Where(x => x.DebtPrefix == "SomeCategory").ToList())
    {
        var transformed = StudentLoanMap.CreateFrom(item);

        customer.Loans.Add(transformed);

        db.Entry(transformed).State = System.Data.EntityState.Added;
    }
}

編集1:

ご指摘のとおり、手動で状態を設定しています。これは、最大のデータベース トランザクション パフォーマンスのために実装されている RecycleContext 呼び出しによるものです。

protected void SaveAndRecycleContext()
{
    db.SaveChanges();
    db.Dispose();
    db = new SolutionDatabase();
    db.Configuration.AutoDetectChangesEnabled = false;
    db.Configuration.ValidateOnSaveEnabled = false;
}
4

1 に答える 1

0

既存のローンかどうかに関係なく、顧客を一掃します。コール時にローンのプロパティ

customer.Loans = new List<Loan>();

于 2013-08-27T13:04:25.217 に答える