我发布这个更多是因为我想了解更多,因为我的解决方法基本上是避免使用LINQ to Entities!如果我可以使用它会很好。所以,如果有人能够启发我..
我正在使用代码优先实体框架作为我的数据模型开发ASP.Net MVC 3应用程序(我的第一个)。它将成为一个在线商店,我正在使用'Admin'控制器,作为管理员,您将能够编辑产品等。在添加新产品时,您必须指定一个类别,这意味着下拉列表。
我首先根据我找到的here信息返回ViewBag中的IEnumerable类别集合。这似乎是处理事情的一种非常好的方式。
但是我得到了同样的错误,你会在下面看到。因此,根据我在线阅读的建议,我创建了一个专门用于创建新产品和编辑现有产品的独立模型。 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 to Entities无法识别方法'System.String ToString()'方法,并且此方法无法转换为商店表达式。”。一个建议的在线解决方案是使用实体框架提供的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.Data.Objects.SqlClient.SqlFunctions'的指定方法'System.String StringConvert(System.Nullable`1 [System.Double])'无法转换为LINQ to Entities商店表达式。“。
我甚至尝试在名为 IdAsString 的数据类中添加只读属性,但这显然使实体框架非常不满意!
最后,我意识到我投入它并不值得,并且完全停止使用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;
}
}
所以,如果有人已经这样做,他们认为他们是以“正确”的方式做到这一点,那么我很想知道你的想法!
答案 0 :(得分:11)
在调用ToString之前使查询具体化将使最后一部分成为非linq-to-entities查询。您可以通过仅选择id和description,然后调用AsEnumerable,然后获取selectlistitems来优化它。
return new DataAccess()
.Categories
.OrderBy(c => c.Description)
.AsEnumerable()
.Select(c => new SelectListItem
{
Value = c.Id.ToString(),
Text = c.Description
});