我正在为在线商店创建产品列表。这是非常标准的东西,产品缩略图页面,包含简要的细节,价格和完整细节的链接。
我正在使用存储库模式,因此我有一个中央数据存储库,它从SQL服务器返回表。为了简洁起见,我已经删除了很多代码,但只是让你明白了:
public class SqlProductsRepository : IProductsRepository
{
private Table<Product> productsTable;
public SqlProductsRepository(string connectionString)
{
var context = new DataContext(connectionString);
productsTable = context.GetTable<Product>();
// More tables set up here
}
public IQueryable<Product> Products
{
get { return productsTable; }
}
// More properties here
}
我将以下对象映射到表:
[Table(Name = "Products")]
public class Product
{
[Column(IsPrimaryKey = true)]
public string ProductCode { get; set; }
[Column]
public string Name { get; set; }
[Column]
public decimal Price { get; set; }
public List<ShopImage> Images = new List<ShopImage>();
}
[Table(Name = "Images_Products")]
public class Image_Product
{
[Column]
public int ImageID { get; set; }
[Column]
public string ProductCode { get; set; }
[Column]
public int DisplayOrder { get; set; }
}
[Table(Name = "Images")]
public class Image
{
[Column(Name = "ImageID")]
public int ImageID { get; set; }
[Column]
public bool Caption { get; set; }
}
如果我执行以下查询:
// 'db' is the repository (member variable of the controller class)
IQueryable<Product> products = from p in db.Products
join ip in db.Image_Product on p.ProductCode equals ip.ProductCode
where ip.DisplayOrder == 0
select p;
我得到了一个很好的IQueryable
个Product
个对象。但是,我想要做的事情是使用单个Images
对象填充每个对象的Image
列表属性,并从已加入的Image_Product
表中设置其ID。
所以我最终得到一个Products
列表,每个Image
属性中都有一个Images
,其中包含DisplayOrder所在数据库中该产品的图像ID 0
我尝试了这个投影,我觉得这很有道理:
IQueryable<Product> products = from p in db.Products
join ip in db.Image_Product on p.ProductCode equals ip.ProductCode
where ip.DisplayOrder == 0
select new Product {
ProductCode = p.ProductCode,
Price = p.Price,
Images = new List<Image> {
new Image { ImageID = ip.ImageID }
}
};
编译但会引发运行时错误:Explicit construction of entity type 'xxx.Product' in query is not allowed.
在项目的其他地方,我这样做:
var pages = from i in db.TemplatePageNavigationItems
orderby i.DisplayOrder
select new NavigationItem {
ID = i.PageID,
ParentID = i.ParentID,
Text = i.Name,
Title = i.Name,
Url = (i.Folder == null) ? "" : i.Folder
};
不要抱怨!我认为这与第一个返回IQueryable<Product>
的查询有关,但我不确定原因。
真的有两个问题:为什么在第一种情况下不允许这样做,为了得到我想要的结果,应该做什么?
答案 0 :(得分:1)
正如错误所述,您无法在查询中构造显式实体类型(Product
就是这样),应返回IQueryable<Product>
。您的pages
查询将返回IEnumerable<NavigationItem>
,而NavigationItem
似乎不是数据库中定义的实体类型。
您可以尝试在第一个查询中返回IEnumerable<Product>
,或者定义一个单独的类型,然后返回IEnumerable
,如果您需要投影一个明确的,自定义的对象实例。