2

私はしばらく問題を抱えていて、自分でこれを理解するためのあらゆる手段を使い果たしました.

MS Sharepoint 2010 環境に、医療グループの個人的な医師データを保持している 2 つのリストがあります...主にテキスト フィールドといくつかのルックアップ選択フィールドだけで特別なものはありません。

リスト A からリスト B にデータを移行するプログラムを作成しようとしています。LINQ to Sharepoint を使用してこれを実現しています。すべて正常にコンパイルされますが、実行して SubmitChanges() メソッドにヒットすると、次のようなランタイム エラーが発生します。

「変更を送信する前に、オブジェクト グラフ内のすべての新しいエンティティを追加/添付する必要があります。」

この問題の解決策が見つからないため、この問題は私の C# 知識の範囲外にあるに違いありません。問題は、一部の列が「ルックアップ」型であるという事実に間違いなく起因しています。これは、LINQ クエリで新しい「医師」エンティティを作成するときに、ルックアップ列を処理するフィールドをコメントアウトすると、すべてが実行されるためです。完璧に。

ルックアップ列が含まれている場合、SubmitChanges() メソッドの前にデバッグしてブレークポイントにヒットすると、古いリストから作成された新しい「Physician」エンティティと、ルックアップ列のデータを含むフィールドを確認できます。新しいエンティティで新しいリストを実際に更新しようとするたびに、フレークアウトするだけです。

このエラーを回避する方法をいくつか試しましたが、すべて役に立ちませんでした。特に、新しい「Physician」エンティティが作成されるたびに、まったく新しい EntityList リストを作成し、Attach() メソッドを呼び出してみましたが、役に立たず、次のような他のエラーを追いかけて、たくさんのサークルに移動するだけです。 「ID を null にすることはできません」、「削除されたエンティティを挿入することはできません」など、

私は最初にこのエラーが発生したときよりも遠くないので、誰でも提供できるヘルプをいただければ幸いです。

これが私のコードです:

using (ProviderDataContext ctx = new ProviderDataContext("http://dev"))
        {

            SPSite sitecollection = new SPSite("http://dev");
            SPWeb web = sitecollection.OpenWeb();
            SPList theOldList = web.Lists.TryGetList("OldList_Physicians");

             //Create new Physician entities.
                    foreach(SPListItem l in theOldList.Items)
                    {
                        PhysiciansItem p = new PhysiciansItem()
                        {
                            FirstName = (String)l["First Name"],
                            Title = (String)l["Last Name"],  
                            MiddleInitial = (String)l["Middle Init"],
                            ProviderNumber = Convert.ToInt32(l["Provider No"]),
                            Gender = ConvertGender(l),
                            UndergraduateSchool =(String)l["UG_School"],
                            MedicalSchool = (String)l["Med_School"], 
                            Residency = (String)l["Residency"],
                            Fellowship = (String)l["Fellowship"], 
                            Internship = (String)l["Internship"],    
                            PhysicianType = ConvertToPhysiciantype(l),
                            Specialty = ConvertSpecialties(l),
                            InsurancesAccepted = ConvertInsurance(l),
                        };
                   ctx.Physicians.InsertOnSubmit(p);
                    }

                    ctx.SubmitChanges(); //this is where it flakes out
        }
    }


     //Theses are conversion functions that I wrote to convert the data from the old list to the new lookup columns.

    private Gender ConvertGender(SPListItem l)
    {
        Gender g = new Gender();
        if ((String)l["Sex"] == "M")
        {
            g = Gender.M;
        }
        else g = Gender.F;
        return g;

    }

    //Process and convert the 'Physician Type', namely the distinction between MD (Medical Doctor) and 
    //DO (Doctor of Osteopathic Medicine).  State Regualtions require this information to be attached 
    //to a physician's profile.
    private ProviderTypesItem ConvertToPhysiciantype(SPListItem l)
    {
        ProviderTypesItem p = new ProviderTypesItem();
        p.Title = (String)l["Provider_Title:Title"];
        p.Intials = (String)l["Provider_Title"];

        return p;
    }

    //Process and convert current Specialty and SubSpecialty data into the single multi-choice lookup column
    private EntitySet<Item> ConvertSpecialties(SPListItem l)
    {
        EntitySet<Item> theEntityList = new EntitySet<Item>();
        Item i = new Item();
        i.Title = (String)l["Provider Specialty"];
        theEntityList.Add(i);            

        if ((String)l["Provider SubSpecialty"] != null)
        {
            Item theSubSpecialty = new Item();
            theSubSpecialty.Title = (String)l["Provider SubSpecialty"];
            theEntityList.Add(theSubSpecialty);
        }

        return theEntityList;
    }


    //Process and add insurance accepted.
    //Note this is a conversion from 3 boolean columns in the SP Environment to a multi-select enabled checkbox
    //list.
    private EntitySet<Item> ConvertInsurance(SPListItem l)
    {
        EntitySet<Item> theEntityList = new EntitySet<Item>();
           if ((bool)l["TennCare"] == true)
                {
                    Item TenncareItem = new Item();
                    TenncareItem.Title = "TennCare";
                    theEntityList.Add(TenncareItem);

                }
         if ((bool)l["Medicare"] == true)
                {
                    Item MedicareItem = new Item();
                    MedicareItem.Title = "Medicare";
                    theEntityList.Add(MedicareItem);
                }
         if ((bool)l["Commercial"] == true)
                {
                    Item CommercialItem = new Item();
                    CommercialItem.Title = "Commercial";
                    theEntityList.Add(CommercialItem);
                }
         return theEntityList;

   }
}
4

1 に答える 1

2

したがって、これはあなたが探している答えではないかもしれませんが、過去に私のために働いたものです. Linq を使用してルックアップ フィールドを SharePoint に更新するのは非常にイライラすることがわかりました。頻繁に機能しないか、効率的に機能しません (ルックアップ値を設定するためだけに ID でアイテムをクエリする必要があります)。

ルックアップ ID (各ルックアップ フィールド) の int プロパティとルックアップ値の文字列プロパティを持つように、エンティティを設定できます。SPMetal を使用してエンティティを生成するときに、検索対象のリストを生成しない場合は、独自にこれを行います。私がやりたいことは(あなたのエンティティを例として使用することです)

  1. Physiciansいくつかの一時フォルダーにその 1 つのリスト ( ) のエンティティを生成します。
  2. ルックアップ (または私が興味を持っているもの) ごとに、ルックアップ ID と値のプロパティを引き出します (乗車のために必要なプライベート バッキング フィールドもあります)。
  3. 実際のプロジェクト ファイルにの部分クラス ファイルを作成してPhysicians、SPMetal ファイル全体を通常どおり (そのリストだけに限定せずに) 再生成しても変更が上書きされないようにする
  4. Physiciansこの部分クラスにルックアップ ID と値のプロパティを貼り付けます。

これで、ルックアップ フィールドごとに 3 つのプロパティが作成されます。たとえば、次のようPhysicianTypeになります。

  • PhysicianType、これは現在そこにあるものです。これは、結合などを非常に簡単に実行できるため、データのクエリを実行する場合に最適です。
  • PhysicianTypeIdこれは、ID のみが必要な場合にクエリに役立つことがありますが、これにより少し簡単になりますが、ほとんどの場合、値を設定するたびに使用します。ルックアップ フィールドを設定するには、 ID を設定するだけです。これは簡単で、私の経験では実際に (正しく) 動作した実績があります。
  • PhysicianTypeValueこれは、ルックアップ値が文字列として必要な場合にクエリを実行するときに役立ちます (つまり、複数値フィールドやユーザー フィールドなどの場合に既に解析されているものではなく、生の値になります。 d むしろ自分で解析するか、開発を行っているときに基礎となる値が何であるかを確認するだけかもしれません.それを使用せずに最初のプロパティを使用する場合でも、私はすでにほとんどのことを行っているため、しばしばそれを一緒に持ってきます.PhysicianTypeIdフィールドを引き継ぐために働きます。

少しハックなようで、linq-to-SharePoint の一般的な設計に反しています。同意しますが、実際に機能し、実際にはそれほど難しくないという利点もあります(一度リズムを取り、プロパティをあるファイルから別のファイルに移動するために正確に何をコピーする必要があるかを学びます)。

于 2012-08-29T16:33:51.173 に答える