连接两个表并从第一个表中选择一个相关值

Posted

技术标签:

【中文标题】连接两个表并从第一个表中选择一个相关值【英文标题】:Joining two tables and selecting a relating value from the first 【发布时间】:2021-04-28 13:42:56 【问题描述】:

我有两个表(简化视图):

产品 产品 ID (PK) 名称 可变乘积(位)

产品变化 ProductVariationId (PK) 名称 产品 ID (FK)

产品图片 ProductImageId (PK) 图片网址 产品 ID (FK) ProductVariationId (FK) NULLABLE

我需要连接这两个表以输出“ProductSearch”列表,这是一个简化的视图模型。

一个产品可以有一个主图像,一个变体可以有它自己的变体图像。

在连接中,如果变体图像值为空,我想为变量产品指定父图像。

我的代码如下:

            //Single products first
            var products = await _context.Product.Where(p => p.Enabled == true && p.VariableProduct == false)
            .Include(e => e.ProductImages.Where(p => p.IsDefault == true && p.ProductVariationId == null))
            .Select(p => new ProductSearch()
            
                ProductId = p.ProductId,
                ProductVariationId = null,
                Name = p.Name,
                ImageUrl = p.ImageUrl.FirstOrDefault().ImageUrl
            ).ToListAsync();

            //Variables
            var productVariables = await _context.ProductVariation
            .Include(p => p.Product).
            .Include(e => e.ProductImages.Where(p.ProductVariationId == e.ProductVariationId))
            .Select(p => new ProductSearch()
            
                ProductId = p.ProductId,
                ProductVariationId = p.ProductVariationId,
                Name = p.Product.Name + " (" +  p.Name + ")",
                ImageUrl =  p.ProductImages.Any() ? p.ProductImages.First().ImageUrl : "PARENT IMAGE NEEDED HERE"
            ).ToListAsync();
            var productSearch = products.Union(productVariables).OrderBy(p => p.Name).ToList();

            return productSearch;

此代码运行良好并按预期生成我的列表,除了字符串“此处需要父图像”之外。

我之前确实问过一个类似的问题(得到了回答),但那是创建一个产品列表,包括它们的变量(如果有的话),而这个列表的不同之处在于它不包括任何类型的任何集合.

非常感谢,像往常一样。

【问题讨论】:

你忘了这里的 lambda 左边吗:.Include(e => e.ProductImages.Where(p.ProductVariationId == e.ProductVariationId))?应该是p=> 你能发布你的课程吗?查询完全错误,我无法对您的模型进行逆向工程。 【参考方案1】:

两件事:

    您只需要在让 EF 构造实体时使用 .Include(x => x.SomeProperty),而不是在选择新对象时使用。 EF 将自动解释您在嵌套属性数据中的选择和连线。

需要包含以便填充 product.ProductImages 的示例:

var p = _context.Product
    // Without this include, the products in the return list will all have null
    // ProductImages property.
    .Include(p => p.ProductImages) 
    .ToList(); // A list of products WITH their ProductImages property populated.

当您不需要使用包含(派生对象/匿名对象)时的示例(显然未针对您的模型进行测试):

var p = _context.Product
    .Select(p => new  // This could be a defined object too such as ProductSearch...
        p.Id,
        p.Name,
        MyDirectImages = p.ProductImages
            // You don't need to filter to this products images because the 
            // ProductImages navigation property is ALREADY only images for this product.
            .Where(i => i.IsDefault && p.ProductVariationId == null)
            .ToList(), // OK, could be .FirstOrDefault() as well if only expecting one.
        MyVariations = p.ProductVariations
            .Select(v => new 
                v.Id,
                v.Name,
                // Once again, the VariationImages (I'm guessing the name...) navigation
                // property is already only images for this variation.
                ImageUrl = v.VariationImages.Where(x => x.IsDefault).FirstOrDefault().ImageUrl
            ).ToList();

    )
    .ToList(); // A list of information about products
    无需解决其他多余的包含,您可以针对您的特定问题执行此操作:

替换

ImageUrl = p.ProductImages.Any() ? p.ProductImages.First().ImageUrl : "PARENT IMAGE NEEDED HERE"

ImageUrl = p.ProductImages.Any() ? p.ProductImages.First().ImageUrl : p.Product.ProductImages.Where(x => x.IsDefault && x.ProductVariationId == null).FirstOrDefault().ImageUrl

【讨论】:

以上是关于连接两个表并从第一个表中选择一个相关值的主要内容,如果未能解决你的问题,请参考以下文章

Pyspark:内部连接两个 pyspark 数据帧并从第一个数据帧中选择所有列,从第二个数据帧中选择几列

从表中选择数据并从另一个表中填充特定值

连接两个表并从一列返回多个匹配项的 SQL 查询?

加入一个包含桥表的表并从主表中获取数据,如果数据存在于桥表中,那么也可以获取它

索引视图中完全外连接的替代方案

我想写两个plsql程序。在一个过程中获取数据并从第二个过程中打印出来