使用原始SQL查询绑定复杂模型实体?

时间:2018-03-01 06:46:13

标签: c# asp.net-mvc entity-framework orm entity-framework-6

我一直在使用实体框架,我可以很容易地与实体本身进行复杂的模型绑定,但是当涉及到原始的sql绑定时,我找不到任何解决方案正在做关系db的复杂绑定。

例如,以下是为产品类 -

建模代码的实体
var prodResult = db.products.Where(p => p.isActive == true).Select(p => new ComplexProductModel
                {
                    id = p.id,
                    dateCreated = p.date_created,
                    datePublished = null,
                    desc = p.product_desc,
                    images = db.products_images.Where(pi => pi.prod_id == p.id).Select(pi => pi.prod_img_thumb).ToList(),
                    summary = p.product_summary,
                    title = p.product_name + " " + p.product_code
                }).ToList();

这可以根据查询要求在主要复杂模型中保存列表类型的字符串或类的复杂模型实现数据。

现在我尝试使用原始sql执行运行相同的生成查询,但图像对象的绑定失败。

var rawComplexData = db.Database.SqlQuery<ComplexProductModel>(dynamicSearchQuery).ToList(); 

对于这种情况是否有任何解决方案,我得到的是10行数据(对于此示例),其中图像为null,应该是7行,其中重复的获取图像进入List<string> images ComplexProductModel }。

以下是更好地理解代码的复杂产品模型:

public ComplexProductModel {
        long? id { get; set; }
        string title { get; set; }
        string desc { get; set; }
        string summary { get; set; }
        List<string> images { get; set; }
        DateTime? datePublished { get; set; }
        DateTime? dateCreated { get; set; }
    }

根据@tchelidze请求,这里是dynamicQuery,这基本上是我从实体框架中产生的东西:

SELECT 
    [Project2].[C1] AS [C1], 
    [Project2].[id] AS [id], 
    [Project2].[date_created] AS [date_created], 
    [Project2].[C2] AS [C2], 
    [Project2].[product_desc] AS [product_desc], 
    [Project2].[product_summary] AS [product_summary], 
    [Project2].[C3] AS [C3], 
    [Project2].[C4] AS [C4], 
    [Project2].[prod_img_thumb] AS [prod_img_thumb]
    FROM ( SELECT 
        [Extent1].[id] AS [id], 
        [Extent1].[product_desc] AS [product_desc], 
        [Extent1].[product_summary] AS [product_summary], 
        [Extent1].[date_created] AS [date_created], 
        1 AS [C1], 
        CAST(NULL AS datetime2) AS [C2], 
        [Project1].[prod_img_thumb] AS [prod_img_thumb], 
        CASE WHEN ([Extent1].[product_name] IS NULL) THEN N'' ELSE [Extent1].[product_name] END + N' ' + CASE WHEN ([Extent1].[product_code] IS NULL) THEN N'' ELSE [Extent1].[product_code] END AS [C3], 
        [Project1].[C1] AS [C4]
        FROM  [dbo].[products] AS [Extent1]
        LEFT OUTER JOIN  (SELECT 
            [Extent2].[prod_id] AS [prod_id], 
            [Extent2].[prod_img_thumb] AS [prod_img_thumb], 
            1 AS [C1]
            FROM [dbo].[products_images] AS [Extent2] ) AS [Project1] ON [Project1].[prod_id] = [Extent1].[id]
        WHERE 1 = [Extent1].[isActive]
    )  AS [Project2]
    ORDER BY [Project2].[id] ASC, [Project2].[C4] ASC

1 个答案:

答案 0 :(得分:1)

你可以引入一个新的对象,例如我们称之为ComplexProductDto,它应该与从SQL返回的查询结果结构完全匹配,例如:

// Please adjust...
public class ComplexProductDto
{
    public int Id { get; set; }
    public int ProductDesc { get; set; }
    ...
    public string ProdImgThumb { get; set; }
}

现在数据将被展平和取消分组,包含重复记录,您可以使用Linq将其分组到内存中。

var rawComplexData = db.Database.SqlQuery<ComplexProductDto>(dynamicSearchQuery).ToList(); 
var prodResult = rawComplexData
  .GroupBy(x => new
  {
      x.Id,
      x.ProductDesc,
      // List all but Image...
  })
  .Select(x => new ComplexProductModel
  {
      id = x.Key.Id,
      desc = x,Key.ProductDesc,
      .... // etc.
      images = x.Select(i => i.ProdImgThumb).ToList()
  });

代码可能不是100%正确但你明白了。该技术是检索未分组的数据并将其分组回所需的结构。