简体   繁体   中英

How can I get a value from this navigation property?

New to Entity Framework and this is confusing me. I have 3 classes "Candidate", "Website" and "WebsiteType". Candidate has a one to many relationship with Website. WebsiteType is purely a lookup table to store the type of site being accessed. I can return the collection of websites for a candidate but cannot figure out how to get the Name property stored in WebsiteType.

Here are the 3 classes:

Candidate.cs
public partial class Candidate
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public Candidate()
        {
            this.Websites = new HashSet<Website>();
        }

        public int Id { get; set; }
        public string LastName { get; set; }
        public string FirstName { get; set; }
        public string MiddleInitial { get; set; }
        public string NickName { get; set; }
        public string PhotoUrl { get; set; }
        public string Address { get; set; }
        public string Phone { get; set; }
        public string Email { get; set; }
        public Nullable<int> NumberOfSignatures { get; set; }
        public Nullable<bool> IncludesSupplementalFiling { get; set; }
        public string Bio { get; set; }
        public Nullable<int> NumberOfVotes { get; set; }
        public Nullable<int> Percentage { get; set; }
        public Nullable<int> CategoryId { get; set; }
        public Nullable<int> OfficeId { get; set; }
        public Nullable<int> PoliticalPartyId { get; set; }

        public virtual Category Category { get; set; }
        public virtual Office Office { get; set; }
        public virtual PoliticalParty PoliticalParty { get; set; }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Website> Websites { get; set; }
    }

Website.cs
public partial class Website
    {
        public int WebsiteId { get; set; }
        public string Url { get; set; }
        public Nullable<int> WebsiteTypeId { get; set; }
        public Nullable<int> CandidateId { get; set; }

        public virtual Candidate Candidate { get; set; }
        public virtual WebsiteType WebsiteType { get; set; }
    }

WebsiteType.cs
 public partial class WebsiteType
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public WebsiteType()
        {
            this.Websites = new HashSet<Website>();
        }

        public int WebsiteTypeId { get; set; }
        public string SiteName { get; set; }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Website> Websites { get; set; }
    }

Below is the code I am using to access the data and project to my DTO. Again my goal is to return the "Name" property from WebsiteType along with my Website collection. Could anyone point me in the right direction?

public CandidateDetailsDTO GetCandidateDetails(int id)
        {
            db.Configuration.LazyLoadingEnabled = false;
            var candidate = (from w in db.Websites
                             join c in db.Candidates on w.CandidateId equals c.Id
                             join wt in db.WebsiteTypes on w.WebsiteTypeId equals wt.WebsiteTypeId
                             select new CandidateDetailsDTO
                            {
                                Id = c.Id,
                                LastName = c.LastName,
                                FirstName = c.FirstName,
                                Bio = c.Bio,
                                Address = c.Address,
                                CategoryName = c.Category.CategoryName,
                                PoliticalParty = c.PoliticalParty.PartyName,
                                Office = c.Office.OfficeName,
                                Websites = w.Candidate.Websites
                            }).FirstOrDefault(c => c.Id == id);

And finally, this is my DTO class:

public class CandidateDetailsDTO
    {
        public int Id { get; set; }
        public string LastName { get; set; }
        public string FirstName { get; set; }
        public string MiddleInitial { get; set; }
        public string NickName { get; set; }
        public string PhotoUrl { get; set; }
        public string Address { get; set; }
        public string Phone { get; set; }
        public string Email { get; set; }
        public string Bio { get; set; }
        public string CategoryName { get; set; }
        public string PoliticalParty { get; set; }
        public string Office { get; set; }

        public ICollection<Website> Websites { get; set; }
    }

I would like to know how I could return the "SiteName" property from WebsiteType with my collection of Websites. Any help would be appreciated.

If you're using proxies (default these days) be sure to use the include function - .Include("Websites.WebsiteType"). If you're storing the entity in your own DTO as a property and passing it around you might want to just disable proxies.

See here for more info - https://msdn.microsoft.com/en-us/library/jj574232(v=vs.113).aspx

So something more like this:

 var candidate = (from curCandidate in db.Candidates.Include("Category").Include("PoliticalParty").Include("Office").Include("Websites").Include("Websites.WebsiteType")
                                where curCandidate.Id == id
                                select new CandidateDetailsDTO
                                {
                                    Id = curCandidate.Id,
                                    LastName = curCandidate.LastName,
                                    FirstName = curCandidate.FirstName,
                                    Bio = curCandidate.Bio,
                                    Address = curCandidate.Address,
                                    CategoryName = curCandidate.Category.CategoryName,
                                    PoliticalParty = curCandidate.PoliticalParty.PartyName,
                                    Office = curCandidate.Office.OfficeName,
                                    Websites = curCandidate.Candidate.Websites
                                }).FirstOrDefault();

Looking closer you might have an error on the Websites bit (essentially have Candidate.Candidate.Websites and I'm not seeing a CandidateID property in your EF class), probably should just be curCandidate.Websites instead of curCandidate.Candidate.Websites

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM