6

我发布这更多,因为我想了解更多,因为我的解决方法已基本避免使用LINQ to Entities!如果我可以使用它会很好。所以,如果任何人都可以开导我..LINQ to Entities ToString() - 建议的解决方案都不工作吗?

我正在使用代码优先的实体框架作为我的数据模型的ASP.Net MVC 3应用程序(我的第一个)。这将成为一个在线商店,我正在'管理员'控制器上工作,作为管理员,您将能够编辑产品等。在添加新产品时,您必须指定一个类别,这意味着下拉列表的类别。

我刚从ViewBag中返回IEnumerable类的集合开始,根据我找到的信息here。这似乎是一个非常好的方法来处理事情。

但我得到了同样的错误,你会看到下面。因此,根据我在线阅读的建议,我创建了一个专门用于创建新的和编辑现有产品的独立模型。 Categories集合用于在视图中构建下拉列表。

public class ProductModel 
{ 
    public int Id { get; set; } 
    public int CategoryId { get; set; } 
    public string Name { get; set; } 
    public string Description { get; set; } 
    public double Price { get; set; } 
    public bool IsVisible { get; set; } 

    public IEnumerable<SelectListItem> Categories 
    { 
     get 
     { 
      return new DataAccess() 
       .Categories 
       .OrderBy(c => c.Description) 
       .Select(c => new SelectListItem 
        { 
         Value = c.Id.ToString(), 
         Text = c.Description 
        }); 
     } 
    } 
} 

这将导致以下错误消息:“LINQ实体无法识别方法‘System.String的ToString()’方法,和这种方法不能被翻译成表达商店。”。一个建议的在线解决方案是使用Entity Framework提供的SqlFunction方法。所以,我想这不是...

public IEnumerable<SelectListItem> Categories 
    { 
     get 
     { 
      return new DataAccess() 
       .Categories 
       .OrderBy(c => c.Description) 
       .Select(c => new SelectListItem 
        { 
         Value = SqlFunctions.StringConvert((double)c.Id), 
         Text = c.Description 
        }); 
     } 
    } 

但是,这将导致该错误消息:“指定的方法‘System.String StringConvert(System.Nullable`1 [System.Double])’的类型” System.Data.Objects.SqlClient.SqlFunctions'不能转换为LINQ to Entities存储表达式。“”。

我甚至尝试在数据类中添加一个只读属性IdAsString,但这显然使Entity Framework非常不快!最后,我意识到,不值得我花费所有时间,并且完全停止使用LINQ。这工作正常,但很高兴知道是否有一个“正确”的方法来做到这一点,实际上工作!

这是我目前工作的解决方案:

public IEnumerable<SelectListItem> Categories 
    { 
     get 
     { 
      var dal = new DataAccess(); 
      var categories = dal.Categories; 
      var items = new List<SelectListItem>(); 

      foreach (var category in categories) 
       items.Add(new SelectListItem 
        { 
         Value = category.Id.ToString(), 
         Text = category.Description 
        }); 

      return items; 
     } 
    } 

所以,如果有人已经这样做的,他们认为他们正在做的“正确”的方式,那么我很想知道你在想什么!

回答

11

在调用ToString之前实现查询将使最后一部分成为非linq-to-entities查询。您可以通过仅选择ID和描述,然后调用AsEnumerable,然后获取selectlistitems来优化此选项。

return new DataAccess() 
     .Categories 
     .OrderBy(c => c.Description) 
     .AsEnumerable() 
     .Select(c => new SelectListItem 
      { 
       Value = c.Id.ToString(), 
       Text = c.Description 
      }); 
+0

哇。这真的很简单 - 谢谢!我有一种感觉,它“应该”很简单! –

+3

您也可以使用'AsEnumerable'而不是'ToList'。分配仅列举的列表是没有意义的。使用'AsEnumerable',您只会枚举一次每个项目,而不是使用'ToList'来查找两次。如果你返回的结果很少,但不会有任何明显的差异。 –