Как заполнить дочернее свойство объекта List запросом LINQ To SQL - PullRequest
0 голосов
/ 09 ноября 2010

Я создаю список товаров для интернет-магазина. Это довольно стандартный материал, страница с миниатюрами товара с краткой информацией, ценой и ссылкой на полную информацию.

Я использую шаблон репозитория, поэтому у меня есть центральное хранилище данных, которое возвращает мне таблицы с 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>, но я не уверен, почему.

На самом деле два вопроса: почему это не разрешено в первой ситуации, и что должен делать, чтобы получить желаемый результат?

1 Ответ

1 голос
/ 09 ноября 2010

Как говорится в ошибке, вы не можете создать явные типы сущностей (Product - это просто) в вашем запросе, который должен возвращать IQueryable<Product>.Ваш запрос pages вернет IEnumerable<NavigationItem>, а NavigationItem не является типом сущности, определенным в базе данных.

Вы можете попробовать вернуть IEnumerable<Product> в своем первом запросе или определить отдельный тип ивместо этого верните IEnumerable этого значения, если вам нужно спроецировать явно настроенные экземпляры объекта.

...