web-dev-qa-db-fra.com

Obtenir plusieurs données de tables à l'aide du modèle de données Entity Framework

J'utilise les données du modèle Entity Framework pour manipuler les données de la base de données (opérations CRUD). Je veux obtenir toutes les données des tables (pas seulement une).

Voici le modèle de base de données:

Database model

Je veux obtenir plusieurs données de toutes les tables. 

Actuellement, j'utilise la requête affichée ci-dessous, mais le problème avec cette requête est que j'ai reçu plusieurs valeurs des tables Contact et que d'autres tables affichent un seul résultat. Est-ce que quelqu'un sait pourquoi ma requête ne fonctionne pas et comment obtenir toutes les données multiples à partir de tables?.

Voici la requête/fonction pour obtenir toutes les données de la base de données:

ContactsEntities db = new ContactsEntities();
        //get all contacts
        public JsonResult GetAll()
        {
            var data = (from c in db.Contacts
                        from e in db.Emails.Where(x => x.id == c.id).DefaultIfEmpty()
                        from p in db.Phones.Where(x => x.id == c.id).DefaultIfEmpty()
                        from t in db.Tags.Where(x => x.id == c.id).DefaultIfEmpty()
                        select new
                        {
                            id = c.id,
                            phones = p.number,
                            emails = e.email1,
                            tags = t.tag1,
                            firstname = c.firstname,
                            lastname = c.lastname,
                            address = c.address,
                            city = c.city,
                            bookmarked = c.bookmarked,
                            notes = c.notes
                        }).ToList();
            return Json(data, JsonRequestBehavior.AllowGet);
        } 
7
jureispro

J'ai testé cela sur votre modèle, cela fonctionne:

var test1 = (from c in db.Contacts
                   join e in db.Emails
                       on c.id equals e.id_contact
                   join t in db.Tags
                   on c.id equals t.id_contact
                   join p in db.Phones on c.id equals p.id_contact
                   select new
                   {
                       id = c.id,
                       phones = p.number,
                       emails = e.email1,
                       tags = t.tag1,
                       firstname = c.firstname,
                       lastname = c.lastname,
                       address = c.address,
                       city = c.city,
                       bookmarked = c.bookmarked,
                       notes = c.notes
                   }).ToList();

J'essayais de résoudre cela en une étape, sinon ajoutez ceci après test1, cela fonctionne correctement:

 var result = (from contact in test1
                    group contact by contact.id into grp
                    select new
                    {
                        id = grp.Key,
                        firstname = grp.First().firstname,
                        lastname = grp.First().lastname,
                        address = grp.First().address,
                        city = grp.First().city,
                        bookmarked = grp.First().bookmarked,
                        notes = grp.First().notes,
                        phones = grp.Where(x => x.phones != null).Select(x => x.phones).Distinct().ToArray(),
                        emails = grp.Where(x => x.emails != null).Select(x => x.emails).Distinct().ToArray(),
                        tags = grp.Where(x => x.tags != null).Select(x => x.tags).Distinct().ToArray()
                    }).ToList();

Si vous établissez la relation entre eux, le problème sera résolu et ce code renverra tous les contacts comme vous le souhaitez:

1- Créer un nouveau diagramme

2- Ajoutez ces tables puis faites glisser l'ID du contact sur 'id_contact' de chaque email, tag et téléphone

3- Sauvegarder le diagramme sur Sql Server

4- Recréez votre modèle dans Visual Studio

Relation

var contacts = (from c in db.Contacts
                       select c).ToList();

pour chaque contact, tous les courriels, téléphones et balises associés seront affichés par la relation.

10
Aria

Vous reliez x.id à c.id. Je pense que vous devez lier x.id_contact à c.id. (même problème pour téléphone et tag)

        var data = (from c in db.Contacts
                    from e in db.Emails.Where(x => x.id_contact == c.id).DefaultIfEmpty()
                    from p in db.Phones.Where(x => x.id_contact == c.id).DefaultIfEmpty()
                    from t in db.Tags.Where(x => x.id_contact == c.id).DefaultIfEmpty()
                    select new
                    {
                        id = c.id,
                        phones = p.number,
                        emails = e.email1,
                        tags = t.tag1,
                        firstname = c.firstname,
                        lastname = c.lastname,
                        address = c.address,
                        city = c.city,
                        bookmarked = c.bookmarked,
                        notes = c.notes
                    }).ToList();
        return Json(data, JsonRequestBehavior.AllowGet);

À en juger par les propriétés "téléphones", "courriels" et "balises" de la sélection, je pense que vous attendez 1 enregistrement par contact. Vous pouvez y parvenir avec un groupe en:

       var data = (from c in db.Contacts
                from e in db.Emails.Where(x => x.id_contact == c.id).DefaultIfEmpty()
                from p in db.Phones.Where(x => x.id_contact == c.id).DefaultIfEmpty()
                from t in db.Tags.Where(x => x.id_contact == c.id).DefaultIfEmpty()
                select new
                {
                    id = c.id,
                    phone = (p != null ? p.number : null),
                    email = (e != null ? e.email1 : null),
                    tag = (t != null ? t.tag1 : null),
                    firstname = c.firstname,
                    lastname = c.lastname,
                    address = c.address,
                    city = c.city,
                    bookmarked = c.bookmarked,
                    notes = c.notes
                }).ToList();

        var data2 = (from i in data
                    group i by i.id into grp
                    select new
                    {
                        id = grp.Key,
                        phones = grp.Where(x => x.phone != null).Select(x => x.phone).ToArray(),
                        emails = grp.Where(x => x.email != null).Select(x => x.email).ToArray(),
                        tags = grp.Where(x => x.tag != null).Select(x => x.tag).ToArray(),
                        firstname = grp.First().firstname,
                        lastname = grp.First().lastname,
                        address = grp.First().address,
                        city = grp.First().city,
                        bookmarked = grp.First().bookmarked,
                        notes = grp.First().notes
                    }).ToList();
1
Tim Eeckhaut

Si la clé externe correspond aux contacts des autres tables, le code suivant fonctionnera en C # - EntityFramework6 - MVC5: 

var conts= db.Contacts;
db.Entry(conts).Collection(c => c.Emails).Load();
// If you retrieve an email, use "Reference" instead of "Collection"

Entity Framework Documentation:

using (var context = new BloggingContext())
{
   var post = context.Posts.Find(2);

   // Load the blog related to a given post
   context.Entry(post).Reference(p => p.Blog).Load();

   // Load the blog related to a given post using a string
   context.Entry(post).Reference("Blog").Load();

   var blog = context.Blogs.Find(1);

   // Load the posts related to a given blog
   context.Entry(blog).Collection(p => p.Posts).Load();

   // Load the posts related to a given blog
   // using a string to specify the relationship
   context.Entry(blog).Collection("Posts").Load();
}
0
zokaee hamid