简体   繁体   中英

Call a method in Linq to EF

In order to create a ViewModel, I tried to call a method GetName() to find the FirstName and LastName for UserID and then add it to the model. But the error tells "Linq to Entities does not recognize the method".

How do I accomplish this in another way?

My code:

public IQueryable<SheetList> GetSheetData()
    {
        var query = from a in GetSheets()
                    select new SheetList
                    {
                        SheetId = a.ListAllSafetySheets.Id,
                        SheetTitle = a.ListAllSafetySheets.SafetySheetTitle,
                        ProductionManagerId = a.ListAllSafetySheets.ProductionManager,
                        ProductionManagerName = this.GetName(a.ListAllSafetySheets.ProductionManager),
                        ConstructionManagerId = a.ListAllSafetySheets.ConstructionManager,
                        Created = a.ListAllSafetySheets.Created,
                        CreatedBy = a.ListAllSafetySheets.CreatedBy,
                        UserProfile_UserId = a.ListAllUserProfiles.UserId,
                        Project_Id = a.ListAllProjects.Id,
                        ProjectLeaderId = a.ListAllProjects.ProjectLeader,
                        ConstructionLocation_Id = a.ListAllConstructionLocations.Id,
                    };
        return query;
    }


public IQueryable<DataCollection> GetSheets()
    {
        var query = from vSafety in _db.Sheets
                    join vUserProfile in _db.UserProfiles
                    on vSafety.Id
                    equals vUserProfile.UserId
                    join vProject in _db.Projects
                    on vSafety.Id
                    equals vProject.Id
                    join vConstructionLocation in _db.ConstructionLocations
                    on vSafety.Id
                    equals vConstructionLocation.Id
                    orderby vSafety.Created descending
                    select new SafetyAndProjectAndUserAndLocationCollection
                    {
                        ListAllSafetySheets = vSafety,
                        ListAllUserProfiles = vUserProfile,
                        ListAllProjects = vProject,
                        ListAllConstructionLocations = vConstructionLocation
                    };
        return query;
    }


public string GetName(int? id)
    { 
        string returnValue;

        if (id == null)
        {
            var userModel = _db.UserProfiles.Single(x => x.UserId == id);

            string FirstName = userModel.FirstName;
            string LastName = userModel.LastName;

            returnValue = FirstName + ", " + LastName;
        }
        else
        {
            returnValue = "";
        }

        return returnValue;
    }

You'll need to call the method after you build the model. You can try something like this:

public IQueryable<SheetList> GetSheetData()
{
    var query = from a in GetSheets()
                select new SheetList
                {
                    SheetId = a.ListAllSafetySheets.Id,
                    SheetTitle = a.ListAllSafetySheets.SafetySheetTitle,
                    ProductionManagerId = a.ListAllSafetySheets.ProductionManager,
                    ProductionManagerName = a.ListAllSafetySheets.ProductionManager,
                    ConstructionManagerId = a.ListAllSafetySheets.ConstructionManager,
                    Created = a.ListAllSafetySheets.Created,
                    CreatedBy = a.ListAllSafetySheets.CreatedBy,
                    UserProfile_UserId = a.ListAllUserProfiles.UserId,
                    Project_Id = a.ListAllProjects.Id,
                    ProjectLeaderId = a.ListAllProjects.ProjectLeader,
                    ConstructionLocation_Id = a.ListAllConstructionLocations.Id,
                };

   var queryWithNames = query.ToList().ForEach(s => s.ProductionManagerName = this.GetName(s.ProductionManagerName));

    return queryWithNames;
}

Since you're having trouble using .ForEach(), you can do this with a regular foreach loop:

foreach(var s in query)
{
    s.ProductionManagerName = this.GetName(s.ProductionManagerName);
}

The downside to this is the call to .ToList will enumerate the queryable, executing the query against the database, so if you need to do further filters later outside this method, you may be downloading additional data that you don't need, causing additional overhead.

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