[FIXED] EF: Rückgabeverbindungstabellen zurückgeben

Ausgabe

Ist dies der richtige Weg, um verknüpfte Tabellen zu erhalten, whereoder gibt es eine andere Möglichkeit, die Daten zurückzugeben?

GetMethod

public IEnumerable<Model.MeetingPollingQuestion> GetMeetingPollingQuestion(int MeetingPollingId)
        {
            using (var db = new NccnEcommerceEntities())
            {
                using (DbContextTransaction dbTran = db.Database.BeginTransaction())
                {
                    var ListOfMeetingPollingQuestions = (from mpq in db.MeetingPollingQuestions
                                                         where (mpq.MeetingPollingId == MeetingPollingId)
                                                         select new Model.MeetingPollingQuestion
                                                         {
                                                             MeetingPollingId = mpq.MeetingPollingId.Value,
                                                             MeetingPollingQuestionType = mpq.MeetingPollingQuestionType,
                                                             MeetingPollingParts = (from mp in db.MeetingPollingParts
                                                                                    where mp.MeetingPollingPartsId == mpq.MeetingPollingId
                                                                                    select new Model.MeetingPollingParts
                                                                                      {
                                                                                          Type= mp.Type
                                                                                      }).ToList(),
                                                         }).ToList();
                    return ListOfMeetingPollingQuestions;
                }
            }
        }

EF-Modell

    namespace Repository.EFModel
    {
        using System;
        using System.Collections.Generic;
        
        public partial class MeetingPolling
        {
            [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
            public MeetingPolling()
            {
                this.MeetingPollingQuestions = new HashSet<MeetingPollingQuestion>();
            }
        
            public int MeetingPollingId { get; set; }
            public Nullable<int> MeetingId { get; set; }
            public Nullable<System.DateTime> StartDate { get; set; }
            public Nullable<System.DateTime> EndDate { get; set; }
            public string PollingTitle { get; set; }
        
            [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
            public virtual ICollection<MeetingPollingQuestion> MeetingPollingQuestions { get; set; }
        }
    }


namespace Repository.EFModel
{
    using System;
    using System.Collections.Generic;
    
    public partial class MeetingPollingQuestion
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public MeetingPollingQuestion()
        {
            this.MeetingPollingParts = new HashSet<MeetingPollingPart>();
        }
    
        public int MeetingPollingQuestionId { get; set; }
        public string MeetingPollingQuestionType { get; set; }
        public Nullable<int> MeetingPollingId { get; set; }
        public Nullable<int> SequenceOrder { get; set; }
    
        public virtual MeetingPolling MeetingPolling { get; set; }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<MeetingPollingPart> MeetingPollingParts { get; set; }
    }
}


namespace Repository.EFModel
{
    using System;
    using System.Collections.Generic;
    
    public partial class MeetingPollingPart
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public MeetingPollingPart()
        {
            this.MeetingPollingPartsValues = new HashSet<MeetingPollingPartsValue>();
        }
    
        public int MeetingPollingPartsId { get; set; }
        public string Type { get; set; }
        public Nullable<int> MeetingPollingQuestionId { get; set; }
    
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<MeetingPollingPartsValue> MeetingPollingPartsValues { get; set; }
        public virtual MeetingPollingQuestion MeetingPollingQuestion { get; set; }
    }
}

Lösung

Ihre Entitäten haben Navigationseigenschaften für die zugehörigen Entitäten. Wenn Sie also Entitäten und ihre Verwandten zurückgeben möchten, laden Sie einfach die zugehörigen Entitäten mit Include.

public IEnumerable<Model.MeetingPollingQuestion> GetMeetingPollingQuestion(int MeetingPollingId)
{
    using (var db = new NccnEcommerceEntities())
    {
        var questions = db.MeetingPollingQuestions
            .AsNoTracking()   
            .Include(mpq => mpq.MeetingPollingType)
            .Include(mpq => mpq.MeetingPollingParts)
            .Where(mpq => mpq.MeetingPollingId == MeetingPollingId)
            .ToList();
        return questions;
    }
}

… und das ist es. Die wichtigen Details hier sind die Verwendung von Include, um verwandte Daten zu laden, und die Verwendung von AsNoTracking, um sicherzustellen, dass die geladenen Entitäten nicht von DbContext nachverfolgt werden. Dies sind getrennte Entitäten, Kopien der Daten, verfolgen aber ansonsten keine Änderungen oder eine Zuordnung zu einem DbContext. Diese eignen sich für den lesenden Zugriff auf die darin enthaltenen Daten.

Whenever returning “entities” outside of the scope of a DbContext you should ensure that they are non-tracked or detached. This is to avoid errors that can come up with potential lazy load scenarios complaining about that an associated DbContext has been disposed, or errors about references being tracked by another DbContext if you try associating these entities to a new DbContext. Your code performing a Select with a new class instance does the same thing, just more code.

Personally I do not recommend working with detached entities such as ever returning entities outside of the scope of the DbContext that they were read from. Especially if you decide you only need a subset of data that the entity ultimately can provide. Entities reflect the data state, and should always be considered as Complete, or Complete-able. (i.e. Lazy loading enabled) If the code base has some code that works with tracked entities within the scope of a DbContext, vs. detached entities, vs. copies of entity classes that might be partially filled or deserialized, it makes for buggy, unreliable, and un-reusable code. Take a utility method that accepts a MeetingPollingQuestion as a parameter. As far as that method is concerned it should always get a complete MeetingPollingQuestion. The behaviour of this method could change depending on whether it was given a tracked vs. detached, vs. partially filled in copy of a MeetingPollingQuestion class. Methods like this would need to inspect the entity being passed in, and how reliable can that logic be for determining why a related entity/collection might be missing or #null?

Wenn Sie Entitätsdaten außerhalb des Bereichs von DbContext übergeben müssen, wo Sie nicht darauf zählen können, dass diese Daten vollständig sind oder zugehörige Daten als letztes Mittel verzögert geladen werden, dann empfehle ich die Verwendung von POCO DTOs oder ViewModels für diese getrennten oder teilweisen Darstellungen der Daten Zustand. Mit einem separaten POCO (Bevölkert von Selectoder Automapper) gibt es keine Verwechslung zwischen dieser Darstellung und einer verfolgten Entität.


Beantwortet von –
Steve Py


Antwort geprüft von –
Terry (FixError Volunteer)

0 Shares:
Leave a Reply

Your email address will not be published. Required fields are marked *

You May Also Like