2017-01-06 6 views
0

私は、データベースからの連絡先を表示し、それらを編集して削除することができ、電子メール/電話/タグのそれぞれを表示する作業アプリケーションを作成しました。データベースに外部キーを追加する - アプリケーションをどのように変更しますか?

データベースは、次のようになります。

Contacts - Id (P), Name, Surname, Address; 
Emails - EntryId (P), PersonId, Email1; 
Telephones - EntryId (P), PersonId, Telephone1; 
Tags - EntryId (P), PersonId, Tag1; 

(Pは、主キーを意味し、PERSONIDがあり、その電子メール人で、常にContactsテーブルから対応するIDです)私は接続していない

どのような方法で私のテーブルは、私はちょうど例えば、このようなIDのIDと人物の電子メールをapproched:

var mailsById = contactsData.Emails.Where(x => x.PersonId == ID).ToList(); 

今私は、私は多分、テーブルエマへの外部キーを追加する必要があります実現ils、電話、タグ、テーブル連絡先からIdに接続されたPersonIdです。だから私は、電子メールでのテーブルdefinitonsにこれを追加しました:

CONSTRAINT [FK_Emails_Contacts] FOREIGN KEY ([PersonId]) REFERENCES [dbo].[Contacts] ([Id]) 

(電話およびタグ付き同じ)

すべてが、それは今EDMX図に、うまくショー(1、*)Contactsテーブルとすべての間の接続を行ってきました他のテーブル(私が望んでいた)が、今私は500(内部サーバーエラー)次の関数で取得します。関数は、データベース内のすべての連絡先に関する完全な情報を返します(フロントエンドでは、名前 - 姓 - メール - 電話 - タグのテーブルがあるので、すべてのテーブルをデータベースから1つのリストに接続しています)。

public JsonResult getAll() 
    { 
     using (ContactsDBEntities contactsData = new ContactsDBEntities()) 
     { 
      List<Contact_Info> completeList = new List<Contact_Info>(); 
      var contacts = contactsData.Contacts; 
      var emails = contactsData.Emails; 
      var telephones = contactsData.Telephones; 
      var tags = contactsData.Tags; 

      //GroupJoin: 
      //Outer.GroupJoin(Inner, outer => key, inner => key, (outer, inner) => result) 

      //first join joins contacts table with emails table 
      var contactList = contacts.GroupJoin(emails, 
       contact => contact.Id, 
       email => email.PersonId, 
       (contact, email) => new 
       { 
        Id = contact.Id, 
        Name = contact.Name, 
        Surname = contact.Surname, 
        Address = contact.Address, 
        Email = email 
       }); 

      //second join joins telephones to the existing contacts-emails list 
      var contactList2 = contactList.GroupJoin(telephones, 
       contact => contact.Id, 
       telephone => telephone.PersonId, 
       (contact, telephone) => new 
       { 
        Id = contact.Id, 
        Name = contact.Name, 
        Surname = contact.Surname, 
        Address = contact.Address, 
        Email = contact.Email, 
        Telephone = telephone 
       }); 

      //third join creates the needed contacts-emails-telephones-tags list 
      var contactList3 = contactList2.GroupJoin(tags, 
       contact => contact.Id, 
       tag => tag.PersonId, 
       (contact, tag) => new 
       { 
        Id = contact.Id, 
        Name = contact.Name, 
        Surname = contact.Surname, 
        Address = contact.Address, 
        Email = contact.Email, 
        Telephone = contact.Telephone, 
        Tag = tag 
       }); 

      //contactList3 to completeList 
      foreach(var contact in contactList3) 
      { 
       Contact_Info temp = new Contact_Info(); 
       temp.Id = contact.Id; 
       temp.Name = contact.Name; 
       temp.Surname = contact.Surname; 
       temp.Address = contact.Address; 
       foreach (var em in contact.Email) 
       { 
        temp.Emails.Add(em); 
       } 
       foreach (var tel in contact.Telephone) 
       { 
        temp.Telephones.Add(tel); 
       } 
       foreach (var tag in contact.Tag) 
       { 
        temp.Tags.Add(tag); 
       } 
       completeList.Add(temp); 
      } 

      return Json(completeList, JsonRequestBehavior.AllowGet);     
     } 
    } 

これは、この機能に使用される私のContact_Infoクラスである:私は、サーバー側のコードをデバッグする試み

public class Contact_Info 
    { 
     public Contact_Info() {} 

     public Contact_Info (string name, string surname, string address, List<Email> emails, List<Telephone> telephones, List<Tag> tags) 
     { 
      Name = name; 
      Surname = surname; 
      Address = address; 
      Emails = emails; 
      Telephones = telephones; 
      Tags = tags; 
     } 

     public int Id; 
     public string Name; 
     public string Surname; 
     public string Address; 
     public List<Email> Emails = new List<Email>(); 
     public List<Telephone> Telephones = new List<Telephone>(); 
     public List<Tag> Tags = new List<Tag>(); 
    } 

、それはexeptionsを返さない:これは、エラーが出力される/:のObjectContextインスタンスを有します接続が必要な操作には使用できなくなります。

テーブルのこの外部キーのプロパティを変更した場合、作業用アプリケーションで変更する必要があることを教えてください。今すぐ実行するのが遅すぎるのですか(つまり、コードを根本的に変更する必要がありますか)、ここでの外部キー制約はどれくらい重要ですか?これは私の最初のデータベースのより複雑なコードでの使用ですので、どうかしてください。間違いをしないでください。

ありがとう!

+0

ObjectContextインスタンスが破棄され、接続を必要とする操作には使用できなくなるというエラーについては、どの行に表示されますか。 – CodingYoshi

+0

@コーディングYoshi Hm、私はそれを見つけることができません、それはエラーが発生する行に記載されていない可能性がありますか? – Filomena

+0

デバッグ中は、アクションメソッドが終了する前にエラーが表示されますか? – CodingYoshi

答えて

0

エンティティ間でナビゲーションプロパティが存在する場合(つまり、データベースからedmxを生成してFK制約が存在する場合)、エンティティを個別に取得してから結合する必要はありません。 Include()を使用してください:

var contacts = contactsData.Contacts 
     .Include(x=>x.Emails) 
     .Include(x=>x.Telephones) 
     .Include(x=>x.Tags) 
     .ToList(); 

私はIncludeがSystem.Data.Entity名前空間の一部だと思います。

+0

System.Dataを追加しました。エンティティの名前空間とは私のgetAll()関数を書き直したので、今では次のようになります。 '公共化するJsonResultのgetAll()を使用して { (ContactsDBEntities contactsData =新しいContactsDBEntities()) { VARの連絡先= contactsData.Contacts .INCLUDE (x => x.Tags) .ToList(); 。 return Json(contacts、JsonRequestBehavior.AllowGet); }} ' – Filomena

+0

は、それはまだエラーを返し、この時間は、出力は次のようになります。_A循環参照「System.Data.Entity.DynamicProxies.Contact_55F0F20179BF8BAB1AC8CFFF6A7F318746B8C25429864C6FAE931BBF884EB6E3」._ – Filomena

+0

の型のオブジェクトをシリアル化しながら、検出されましたので、あなたは、データを取得していると、シリアライズしますが、親には子への参照があり、子には親への参照があります。だから、シリアル化するときに無限の循環参照があります。あなたがする必要があるのは、各子モデルに行き、親を指し示すナビゲーションプロパティに[JsonIgnore]属性を追加することです。その属性はnewtonsoft名前空間にあります。これにより、シリアライザは、子モデルで再び親を直列化する必要がないことを通知します。モデルからデータベースを再生成する場合は、属性を再度追加する必要があります。 – ATerry

関連する問題