【问题标题】:Call a method in Linq to EF在 Linq to EF 中调用方法
【发布时间】:2012-10-30 17:36:41
【问题描述】:

为了创建 ViewModel,我尝试调用 GetName() 方法来查找 UserID 的 FirstName 和 LastName,然后将其添加到模型中。但错误告诉“Linq to Entities 无法识别该方法”。

我如何以另一种方式完成此任务?

我的代码:

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;
    }

【问题讨论】:

  • GetName() 是做什么的? Linq to Entity 查询被转换为 SQL。如果您调用任意方法,则无法将其转换为 SQL,因此您会看到失败。但是,如果该方法仅对数据库中的数据进行操作,则可能以一种可以将其转换为 SQL 的方式更改您的查询,并且您不必评估计算即可调用任意客户端上的方法。
  • @Pawel 他包含了 GetName() 的定义。向下滚动。
  • @KyleTrauberman - 谢谢。我错过了这个。

标签: asp.net-mvc linq-to-entities asp.net-mvc-viewmodel


【解决方案1】:

您需要在构建模型后调用该方法。你可以试试这样:

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;
}

由于您在使用 .ForEach() 时遇到问题,您可以使用常规的 foreach 循环来执行此操作:

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

这样做的缺点是对 .ToList 的调用将枚举可查询对象,对数据库执行查询,因此如果您稍后需要在此方法之外进行进一步过滤,您可能会下载不需要的其他数据,导致额外的开销。

【讨论】:

  • 非常感谢!我收到错误消息“不包含 'Foreach' 的定义,并且没有扩展方法 'Foreach' 接受 System.Collections.Generic.List 类型的参数可以找到(您是否缺少 using 指令或程序集引用)"
  • 确保在文件顶部引用了System.Core.dllusing System.Collections.Generic
  • 是的,我已经引用了它。并且没有提示可以解决缺少的参考。上下文菜单中没有解决选项。
  • 尝试删除引用并重新添加?您使用的是哪个版本的 .NET 框架?
  • 它没有帮助。我在 MVC 4 项目中使用 .NET 4.0、EF 4.4。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-16
  • 1970-01-01
相关资源
最近更新 更多