3

これが可能かどうかはわかりませんが、データベースに多くのエンティティを挿入しており、各アイテムについて、エンティティである言語プロパティが示されています。現在、挿入されるアイテムごとに新しい言語オブジェクトを作成していますが、これは多くの重複を作成するため、テスト用です。言語はデータベース内で一意であり、既存の言語レコードを指している必要があります。私が考えることができる唯一の方法は、挿入ごとに個別のサービス呼び出しを実行して、言語コードを検索し、既存の言語のIDを取得することです。多くのオーバーヘッド。

言語コードに基づいてレコードを自動的に検索し、そのレコードを使用する方法はありますか?

ありがとう

4

3 に答える 3

4

との両方ObjectContextDbContext、メモリ内のコンテキストからすでにロードされているエンティティを検索しようとするメソッドがありますGetObjectByKey-forObjectContextおよびFindfor DbContext。これらのメソッドを使用するとLanguage、データベースからエンティティを複数回ロードすることを回避できます。

どちらの方法でも、エンティティをキーで検索するための入力パラメータとして主キー値が必要です。基本的に、これらのメソッドは、主キーをエンティティオブジェクトに関連付ける内部ディクショナリにアクセスするものと考えてください。

さて、あなたのコメントを参照してください...

基本的に、id /主キー値ではなく、カスタム値と一致させようとします。

...これらのメソッドは、検索する主キーの値を知っていることに依存しているため、使用できません。

私がすることは、主キーではなくエンティティに「カスタム値」を関連付ける独自のディクショナリによって、前述の内部ディクショナリのロジックを模倣することです。カスタム値はLanguageテーブル内で一意であると想定しています。

したがって、アイデアは次のようになります。

このようなエンティティがあるとすると...

public class MyEntity
{
    public int Id { get; set; }
    public Language Language { get; set; }
    public string SomeOtherValue { get; set; }
    // ... more
}

public class Language
{
    public int Id { get; set; }             // primary key value
    public string CustomValue { get; set; } // the unique custom value
    // ... more
}

...そして、新しいエンティティを挿入するために使用しているデータのコレクションがあります...

public class Data
{
    public string SomeOtherValue { get; set; }
    public string LanguageCustomValue { get; set; }
    // ... more
}

var dataList = new List<Data>
{
    new Data { SomeOtherValue = "A", LanguageCustomValue = "EN" },
    new Data { SomeOtherValue = "B", LanguageCustomValue = "FR" },
    new Data { SomeOtherValue = "C", LanguageCustomValue = "EN" },
    new Data { SomeOtherValue = "D", LanguageCustomValue = "EN" },
    // ... more
}

...次に、これを使用できます:

using (var context = new MyContext())
{
    var dict = new Dictionary<string, Language>();
    foreach (var data in dataList)
    {
        Language language;
        if (!dict.TryGetValue(data.LanguageCustomValue, out language))
        {
            // load the language only once from the database
            language = context.Languages.SingleOrDefault(l =>
                l.CustomValue == data.LanguageCustomValue);
            dict.Add(data.LanguageCustomValue, language);
        }

        var myEntity = new MyEntity
        {
            SomeOtherValue = data.SomeOtherValue,
            Language = language
        };

        context.MyEntities.Add(myEntity);  // or AddObject
    }
    context.SaveChanges();
}

Languageこれにより、ごとに1つのエンティティのみがロードされ、これは1回だけ実行され、データベース内LanguageCustomValueにオブジェクトの複製は作成されません。Language

于 2012-09-21T13:33:29.583 に答える
1

ここで何を意味するのか正確にはわかりませんが、挿入中にある場合は、通常、存在するかどうかを確認し、存在しない場合は追加します。多数のエンティティを挿入する場合は、言語をコンテキストに保存できます。ただし、これが最善の解決策かどうかはわかりません。キーなしでストアまたはコンテキスト内のオブジェクトをすばやく見つける方法があるとは思わないでください。言語エンティティの複雑さに応じて、コンテキスト'languages'変数をToDictionary()の下にキャストし、代わりにそれをロールスルーすることができます。

//'db' is your context here.
var languages = db.Languages.all();
myentity MyEntity = new MyEntity();
myentity.property1 = "mynewvalue1";

var newlang = new Language{ LanguageName= "newlanguagename"};
//language exists?
if (!languages.Any( u => u.LanguageName== newlang.LanguageName ))
 {

  // no:
  db.Languages.InsertOnSubmit(newlang);
  db.SubmitChanges();
  myentitly.Language = newlang;
 }
else{

  //yes:
  myentitly.Language = languages.Where( u => u.LanguageName== newlang.LanguageName).Single();
 }

db.MyEntities.InsertOnSubmit(myentity);
db.SubmitChanges();
于 2012-09-26T23:22:57.477 に答える
1

オーバーヘッドのパフォーマンスコストが懸念されるため、これを処理する最も効率的な方法としてこれをお勧めします。

ステップ1:言語テーブルが正しいことを確認します。

使用する言語をどのように定義するかわからないため、ここではお手伝いできません。言語テーブルに必要なすべての行が含まれていることを確認してください。テーブルが次のようになっていると仮定します。

{ Id: 1 ; Language: "English" }
{ Id: 2 ; Language: "French"  }
{ Id: 3 ; Language: "German"  }

ステップ2:エンティティを処理する

ステップ2.1:Dictionary<string, int>言語テーブルを簡単にマッピングするためのを作成します。

var lang_list = new Dictionary<string, int>();

using(var db = new DbContext()
{
     foreach(var row in db.Languages.ToList())
     {
            lang_list.Add(row.Language, row.Id);
     }
}

//From now on, you can refer to the local list.

ステップ2.2:(追加される)エンティティに正しい言語を追加する

追加する必要のある言語をどのように決定するかわかりません。myLanguage必要な言語の文字列名を含む文字列変数があると仮定しましょう。

次のようなものを使用することをお勧めします。

int foundvalue;

if(lang_list.TryGetValue( myLanguage , out foundvalue ))
{
     //if language is in the list, the value (= the id of the row in the language
     // table) will be stored in foundvalue
     myEntity.LanguageId = foundvalue;
}
else
{
     //if the language wasn't found in the list, set a default lang (e.g. English)
     myEntity.LanguageId = 1;
}

これがあなたの問題に役立つことを願っていますか?

このプロセスを使用する利点:

  • 言語についてデータベースにクエリを実行する必要があるのは1回だけです。リストにデータが入力されると、メモリに保存されます。これは、パフォーマンスの面で優れた方法です。
  • エンティティに予期しない言語または正しくない言語が設定されている場合は、デフォルトの言語にフォールバックできます。
于 2012-09-27T12:32:21.527 に答える