Я создаю список товаров для интернет-магазина. Это довольно стандартный материал, страница с миниатюрами товара с краткой информацией, ценой и ссылкой на полную информацию.
Я использую шаблон репозитория, поэтому у меня есть центральное хранилище данных, которое возвращает мне таблицы с 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
.
Таким образом, я получаю список Products
, каждый с одним Image
в своем свойстве Images
, в котором указан идентификатор изображения для этого продукта в базе данных, где DisplayOrder равен 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>
, но я не уверен, почему.
На самом деле два вопроса: почему это не разрешено в первой ситуации, и что должен делать, чтобы получить желаемый результат?