Linq:从值为非null的表中连接表

时间:2014-07-26 13:10:50

标签: c# sql linq

我有四张桌子。

ProductFormula

   Sku             Param1  Param2
   -------------------------------
   100203          1.2      1.1
   100204          1.3      1.0
   .....
   ....

CategoryFormula

 CategoryId        Param1  Param2
 ---------------------------------
   382               1.5      1.2
   383               1.6      1.4
   .....
   ....

Product

   Id    CategoryId 
  ------------------
   1     383
   2     384

ProductVariant

   Id  ProductId   Sku
   --------------------------
   1     1         100203
   ....

我想记录,如果产品公式存在,则应使用linq查询以其他方式使用产品。

任何帮助?

1 个答案:

答案 0 :(得分:1)

我明白了你想要实现的目标。基本上,您想要为产品返回ProductFormula。如果指定的产品没有ProductFormula,则回退到返回CategoryFormula。

这假定Product始终具有ProductCategory,并且每个类别轮流始终具有CategoryFormula。

注意:在下面的示例中,我故意不将所有内容链接到一个大的Linq查询中。这看起来真的很酷,但在可读性方面却很荒谬。我赞成最后一个,并附上一些评论,希望让一切更容易理解:

    /// <summary>
    /// Returns either a ProductFormula, if it exists for the specified Product, otherwise a general CategoryFormula.
    /// </summary>
    static dynamic RetrieveFormula(int productId)
    {
        // First, we need to combine the entities 'Product' with 'ProductVariant'. 
        // This because we need the 'SKU' to check if a ProductFormula exists:
        var combinedProducts = AllProducts.Join(

            // join 'Products' and 'ProductVariants'
            AllProductVariants, 
            product => product.Id,
            productvariant => productvariant.ProductId,
            (product, productvariant) => new {
                Product = product,
                Variant = productvariant
            })

            // create a 'merged', anonymous object which holds all the info we need
            .Select(p => new
            {
                ProductId = p.Product.Id,
                CategoryId = p.Product.CategoryId,
                SKU = p.Variant.SKU
            });    

        // With this in place, we can now fetch the requested record by 'productId'
        var product = combinedProducts.Single(p => p.ProductId == productId);

        // Finally, check if there's a ProductFormula
        if (AllProductFormulas.Any(p => p.SKU == product.SKU))
            // yes, there's a ProductFormula so return it
            return AllProductFormulas.Single(pv => pv.SKU == product.SKU);
        else
            // no, sorry - simply return the CategoryFormula instead
            return AllCategoryFormulas.Single(c => c.Id == product.ProductId);
    }

你明确要求返回A,否则,B.因此,该函数返回动态结果。您也可以组合结果并返回一组动态属性。对于最佳实践,您可能希望引入要继承的超类或接口。

最后提示:大多数现代ORM,例如EntityFrameworkServerStack OrmLite,仅举几例,内置关系,这将使您的编码体验更容易进行这些相关查询。

希望这能为你做好准备......