-1

しばらくの間、Entity Framework 6を​​使用しています。.net c#アプリケーションループからSQL Serverデータベーステーブルの何百ものレコードを適切かつ効率的に更新します。

しかし、私はすべてのユーザーをループに300人の-1000ユーザー

、それは非常に非効率的になるだろうし、DBにいくつかの列を更新するのが遅いですを必要としています。 EF6.xで?代わりにADO.NETを使用するか、ワイヤを介して何らかのオブジェクトを送信する必要があります。

現在、私は私が他のユーザーに掛けあれば、基本的にそれはOKだろう。この

rpmuser.usr_id = user; 
rpmuser = db.rpm_usr.Find(rpmuser.usr_id); 
rpmuser.lst_pwd_chg_dtm = dateTime; 
rpmuser.cre_dtm = dateTime; 

rpmuser.usr_pwd = hash; 
rpmuser.salt = salt; 

db.SaveChanges(); 

のように更新しますか?どのように私は一括更新でこれを行うことができますか?あなたがこのテストするには、次のコードを使用することができます

for(.... ) { 
    // different user id 
    // all the other needed poco model changes above... etc. 
    // db.SaveChanges() 
} 
+0

をのhttp:// stackoverflowの。com/questions/29892410/update-records-in-foreach-loop-in-entity-framework-6)を参照してください。正しい方向に向けるかもしれません。 –

+1

最終的なパフォーマンスが目標である場合は、更新ステートメントを書き込んでDbに渡すか、spocを作成してコードから呼び出します。 –

+1

1,000レコードはあまりありません。ループ内でFind()とSaveChanges()を実行しないでください。コレクション、ループ、SaveChanges()を一度取得してください。 –

答えて

0

:適切かつ効率的にレコードの数百を更新するには

static void Main(string[] args) 
{ 
    CreateAndSeedTheDatabase(); // Step 1: run this 
    //UpdateAllOfTheProducts(); // Step 2: Comment out the above line and uncomment and run this line 
} 

static void CreateAndSeedTheDatabase() 
{ 
    Context context = new Context(); 
    context.Database.Initialize(true); 

    Product product; 
    for (int i = 0; i < 1000; i++) 
    { 
     product = new Product() { ProductId = i, Name = "Product" + i }; 
     context.Products.Add(product); 
    } 
    context.SaveChanges(); 
} 

static void UpdateAllOfTheProducts() 
{ 
    Context context = new Context(); 
    Product[] products = context.Products.ToArray(); 
    foreach (Product product in products) 
    { 
     product.Name = product.ProductId + "Product"; 
    } 
    context.SaveChanges(); 
} 

public class Context : DbContext 
{ 
    public Context() 
    { 
     Database.SetInitializer(new DropCreateDatabaseIfModelChanges<Context>()); 
    } 
    public DbSet<Product> Products { get; set; } 
} 

public class Product 
{ 
    public int ProductId { get; set; } 
    public string Name { get; set; } 
} 

}

+0

私はInsertに必要な新しいレコードではありませんが、Update、すべての列を更新せずに.Add(モデル)とSaveChanges()を実行しようとしていました。私はSaveChanges()の前にFind()を使って作業するように変更したので、forループでSaveChanges()を実行してはいけませんでしたが、渡されるFind(ユーザー)はどうでしょうか?受信したユーザーパラメータなどがあります。 –

+0

このコードをコンソールアプリケーションで実行しようとしましたか? UpdateAllOfTheProductsメソッドは、CreateAndSeedTheDatabaseメソッドによって作成されたデータベース内の既存のレコードをすべて更新します。 – bwyn

0

を、あなたは、可能な限りデータベース・ラウンドトリップを削減する必要があります。あなたのケースでは

、あなたは重いデータベース往復

を使用すると、データベースの往復を作っている、あなたが更新する必要があるすべてのユーザーのための方法

を検索する2つの方法があります。これを迅速に減らす方法はいくつかあります。 (データベースが何百万ものユーザーが含まれていない場合はうまく動作!)

  • ロードするすべてのユーザーとは、唯一のデータベース・ラウンドトリップを作るために重要な「usr_id」と辞書を使用

  • 作成

    // Work well if the database doesn't contain to much users 
    var userDict = db.rpm_usr.ToList().ToDictionary(x => x.usr_id); 
    
    
    // Be careful, the list cannot contains more than 2099 items (SQL Parameters limit = 2100) 
    var userDict = db.rpm_usr.Where(x => ids.Contains(x.usr_id)).ToDictionary(x => x.usr_id); 
    
    :リストには、すべての "usr_id" と一度使用した時にすべてのユーザーを取得してメソッド

例が含まれています

どちらのソリューションでも、データベースのラウンドトリップは1回だけ実行され、辞書からユーザーを非常に効率的に取得できます。

のSaveChangesメソッド

のSaveChangesメソッドは、すべてのレコードを更新するためのデータベース・ラウンドトリップを行います。したがって、1000人のユーザーを更新すると、データベースの往復が非常に遅くなります。

免責事項:私は劇的にパフォーマンスを向上させるためにEntity Framework Extensions

このプロジェクトは、BulkSaveChangesを実行することを可能にするプロジェクトの所有者とBulkUpdateよ:(以下の[リンク]を参照してください

for(.... ) { 
    // different user id 
    // all the other needed poco model changes above... etc. 
    db.BulkSaveChanges() 
} 

for(.... ) { 
    // different user id 
    // all the other needed poco model changes above... etc. 
    db.BulkUpdate(users) 
} 
関連する問題