MVC 4. and Entity Framework Table Join

16,854

Solution 1

Project to an anonymous object

var query = from o in db.ADPerson
   join c in db.MsdnTypes on o.MsdnTypeId equals c.MsdnTypeId
   select new 
   {
     AdPersonId        = o.AdPersonId,
     SamAccountName    = o.SamAccountName,
     Description       = o.Description,
     DisplayName       = o.DisplayName,
     UserPrincipalName = o.UserPrincipalName,
     Enabled           = o.Enabled,
     LastUpdated       = o.LastUpdated,
     OnlineAssetTag    = o.OnlineAssetTag,
     MsdnTypeId        = o.MsdnTypeId,
     MsdnSubscription  = c.MsdnTypeDescription,
  };

Then map back to your entity

foreach (var item in query)
{
  var adPerson = new ADPerson
  {
    AdPersonId         = item.AdPersonId,
    SamAccountName     = item.SamAccountName,
    Description        = item.Description,
    DisplayName        = item.DisplayName,
    UserPrincipalName  = item.UserPrincipalName,
    Enabled            = item.Enabled,
    LastUpdated        = item.LastUpdated,
    OnlineAssetTag     = item.OnlineAssetTag,
    MsdnTypeId         = item.MsdnTypeId,
    MsdnSubscription   = item.MsdnTypeDescription,
  {
}

Solution 2

   public IQueryable<ADPerson> FindAll(string UserId)
    {
       // return (from p in db.ADPerson
       //        select p);
        List<ADPerson> lst = new List<ADPerson>();
        var query = from o in db.ADPerson
                    join c in db.MsdnTypes on o.MsdnTypeId equals c.MsdnTypeId
                    select new
                         {

                             AdPersonId = o.AdPersonId,
                             SamAccountName = o.SamAccountName,
                             Description = o.Description,
                             DisplayName = o.DisplayName,
                             UserPrincipalName = o.UserPrincipalName,
                             Enabled = o.Enabled,
                             LastUpdated = o.LastUpdated,
                             OnlineAssetTag = o.OnlineAssetTag,
                             MsdnTypeId = o.MsdnTypeId,
                             MsdnSubscription = c.MsdnTypeDescription

                         };
        foreach (var item in query)
        {
            var adPerson = new ADPerson()
              {
                  AdPersonId = item.AdPersonId,
                  SamAccountName = item.SamAccountName,
                  Description = item.Description,
                  DisplayName = item.DisplayName,
                  UserPrincipalName = item.UserPrincipalName,
                  Enabled = item.Enabled,
                  LastUpdated = item.LastUpdated,
                  OnlineAssetTag = item.OnlineAssetTag,
                  MsdnTypeId = item.MsdnTypeId,
                  MsdnSubscription = item.MsdnSubscription
              };
            lst.Add(adPerson);

        }

        return lst.AsQueryable();



    }
Share:
16,854

Related videos on Youtube

David Costelloe
Author by

David Costelloe

Updated on May 25, 2022

Comments

  • David Costelloe
    David Costelloe almost 2 years

    This item is driving me mad ;-) I am trying to do a simple query joining two tables

    I have the following:

    Repository Class method

     public IQueryable<ADPerson> FindAll(string UserId)
        {
            return (from p in db.ADPerson
                    select p); 
    
    
        }
    

    In my Controller:

      var ADPersonList = from o in ADPersonDB.FindAll(GetUserId())
                        join c in MSDNTypeDB.FindAll(GetUserId()) on o.MsdnTypeId equals c.MsdnTypeId
                        select new ADPerson()
                        {
    
                            AdPersonId = o.AdPersonId,
                            SamAccountName = o.SamAccountName,
                            Description = o.Description,
                            DisplayName = o.DisplayName,
                            UserPrincipalName = o.UserPrincipalName,
                            Enabled = o.Enabled,
                            LastUpdated = o.LastUpdated,
                            OnlineAssetTag = o.OnlineAssetTag,
                            MsdnTypeId = o.MsdnTypeId,
                            MsdnSubscription = c.MsdnTypeDescription,
    
    
                        };
    

    I keep getting an error:

    {"The specified LINQ expression contains references to queries that are associated with different contexts."}
    

    I also tried adding to the repository class:

    Repository Class method

     public IQueryable<ADPerson> FindAll(string UserId)
        {
            //return (from p in db.ADPerson
            //        select p); 
    
            var query = from o in db.ADPerson
                        join c in db.MsdnTypes on o.MsdnTypeId equals c.MsdnTypeId
                        select new ADPerson()
                        {
    
                            AdPersonId = o.AdPersonId,
                            SamAccountName = o.SamAccountName,
                            Description = o.Description,
                            DisplayName = o.DisplayName,
                            UserPrincipalName = o.UserPrincipalName,
                            Enabled = o.Enabled,
                            LastUpdated = o.LastUpdated,
                            OnlineAssetTag = o.OnlineAssetTag,
                            MsdnTypeId = o.MsdnTypeId,
    
                            MsdnSubscription = c.MsdnTypeDescription,
    
    
                        };
    
            return query;
    
        }
    

    is it really so hard to do a simple join between two tables and populate the variable in Entity framework

    Thanks

    • mattytommo
      mattytommo about 11 years
      Is it the same error using the second method?
    • David Costelloe
      David Costelloe about 11 years
      Excellent point: No the error returned on the second is: The entity or complex type 'project.Models.ADPerson' cannot be constructed in a LINQ to Entities query.
    • Forty-Two
      Forty-Two about 11 years
      RE: the second error. That's because you cannot project onto a mapped entity. You may project the query to an anonymous object, and then map it to the ADPerson entity afterwards
    • Forty-Two
      Forty-Two about 11 years
      Alternatively, you may choose to create an un-mapped DTO, project to that, then map back to the ADPerson entity.
    • David Costelloe
      David Costelloe about 11 years
      Oh so return as List rather than IQuerable? Sorry little confused as both tables are mapped in repository classes..ok not sure how to create an un-mapped DTO and map back again
  • David Costelloe
    David Costelloe about 11 years
    The first var query is failing is there suppose to be select new?
  • Forty-Two
    Forty-Two about 11 years
    @DavidCostelloe yes, sorry. Edited answer
  • eburgos
    eburgos about 11 years
    it might be you have a trailing comma at "MsdnSubscription = c.MsdnTypeDescription," and also on the second one
  • David Costelloe
    David Costelloe about 11 years
    Thanks found it was the brace { and }; almost there :-)
  • David Costelloe
    David Costelloe about 11 years
    getting error "Invalid column name 'MsdnSubscription" on display of field
  • David Costelloe
    David Costelloe about 11 years
    I should be returning query but it says I can't due to being anonymous.
  • David Costelloe
    David Costelloe about 11 years
    Looks like I need to convert the anonymous to Iquerable<ADPerson> any ideas on how i can do that. Does seem like an aweful lot of trouble to join a table in the Entity framework there must be an easier way?
  • Forty-Two
    Forty-Two about 11 years
    @david that's what the for each loop does. It converts each anonymous object returned by the query to an ADPerson entity. Just declare a new list of ADPerson and add each entity to the list as it is converted.
  • David Costelloe
    David Costelloe about 11 years
    thanks once you mentioned that it became obvious on what was needed. Finally works the way it should. Updated as answered and complete. I spend way to much trying to come up with a complex way when I should have been looking to the simple way :-(