2015-04-03 118 views
0

我終於能夠構造一個多映射查詢並返回有意義的數據。該查詢返回了一個自定義對象的列表,該自定義對象本身由一些其他對象組成。但是這個查詢使用一個參數。WHERE子句中的Dapper和DateTime會導致多重映射的空值

當我通過添加第二個參數DateTime修改此查詢時,兩個聚合對象(零件和顏色)爲空。但是,當我在探查器中捕獲SQL並在SQL Server中運行它時,所有數據都在那裏!

如何更好地處理where子句中的DateTime參數?顯然這是導致問題的原因。

下面的代碼使用註釋掉的where子句,但不是現有的子代碼。

public IList<PartReceipt> GetReceiptHistory(ListItem supplier, DateTime dateReceived) 
    { 
    const string sql = 
     @"SELECT r.id, r.Quantity, r.UnitCost, r.DateReceived, 
       s.Id , s.Description, 
       p.Id, p.Number, p.Description, p.StockClass, 
       mp.Id , mp.Number, mp.ManufacturerId, mp.Description, 
       m.Id , m.Description, m.ShortDescription, 
       c.Id, c.Description, 
       pc.Id, pc.Name, pc.Description 
      FROM PartReceipt r 
      INNER JOIN Supplier s ON r.SupplierId = s.Id 
      INNER JOIN Part p on r.PartId = p.Id 
      INNER JOIN ManufacturerPart mp ON p.ManufacturerPartId=mp.Id 
      INNER JOIN Manufacturer m ON mp.ManufacturerId = m.Id 
      LEFT JOIN Color c ON p.ColorId=c.Id 
      LEFT JOIN ProductCategory pc ON p.ProductCategoryId=pc.Id 
      WHERE [email protected] AND r.DateReceived = @dateReceived"; 

    //   WHERE [email protected]"; 
    IList<PartReceipt> reportData; 
    using (DbConnection connection = ConnectionFactory.GetOpenConnection()) 
    { 
     reportData = connection.Query<PartReceipt>(sql, 
      new 
      { 
       supplierId = supplier.Id, 
       dateReceived 
      }).ToList(); 
    } 
    return reportData; 
    } 

而且支持類是:

public class PartReceipt 
    { 
    public int Id { get; set; } 
    public Supplier Supplier { get; set; } 
    public Part Part { get; set; } 
    public DateTime DateReceived { get; set; } 
    public Decimal UnitCost { get; set; } 
    public int Quantity { get; set; } 
    } 

    public class Part 
    { 
    public Color Color { get; set; } 
    public string Description { get; set; } 
    public int Id { get; set; } 
    public ManufacturerPart ManufacturerPart { get; set; } 
    public string Number { get; set; } 
    public string PicturePath { get; set; } 
    public ProductCategory ProductCategory { get; set; } 
    public string StockClass { get; set; } 
    } 

    public class ManufacturerPart 
    { 
    public string Description { get; set; } 
    public int Id { get; set; } 
    public int ManufacturerId { get; set; } 
    public string Number { get; set; } 
    public Manufacturer Parent { get; set; } 
    } 

    public class Manufacturer 
    { 
    public string Description { get; set; } 
    public int Id { get; set; } 
    public string ShortDescription { get; set; } 
    } 

    public class ProductCategory 
    { 
    public string Description { get; set; } 
    public int Id { get; set; } 
    public string Name { get; set; } 
    } 

    public class Color 
    { 
    public string Description { get; set; } 
    public int Id { get; set; } 
    } 
+0

我很驚訝這個作品。如何精確地知道7個id和5個描述中的哪一個映射到哪裏。猜猜它回頭看錶名和別名然後 – Mackan 2015-04-03 22:09:45

+0

我也很驚訝。但是,如果我像我一樣按對象排序SQL查詢,它就會起作用。如果我把訂單混合起來,結果很糟糕。例如,「顏色描述」可能已轉到「零件描述」。 – user2443507 2015-04-03 22:43:07

+0

我認爲這可能是由於,例如,結果集中'Color.Id'爲空。然後'Part.Color'將爲空,然後'PartReceipt.Part'變爲null。一連串不可映射的對象。但我不確定。如果您想要將問題添加到該問題,則查詢的輸出可能會提示您。 – Mackan 2015-04-04 10:48:19

回答

0

我很抱歉,我沒有張貼此問題之前更加謹慎。我沒有正確構建多映射查詢。當我做,它的作品。

public IList<PartReceipt> GetReceiptPart(ListItem supplier, DateTime dateReceived) 
    { 
    const string sql = 
     @"SELECT r.id, r.Quantity, r.UnitCost, r.DateReceived, 
       s.Id , s.Description, 
       p.Id, p.Number, p.Description, p.StockClass, 
       mp.Id , mp.Number, mp.ManufacturerId, mp.Description, 
       m.Id , m.Description, m.ShortDescription, 
       c.Id, c.Description, 
       pc.Id, pc.Name, pc.Description 
      FROM PartReceipt r 
      INNER JOIN Supplier s ON r.SupplierId = s.Id 
      INNER JOIN Part p on r.PartId = p.Id 
      INNER JOIN ManufacturerPart mp ON p.ManufacturerPartId=mp.Id 
      INNER JOIN Manufacturer m ON mp.ManufacturerId = m.Id 
      LEFT JOIN Color c ON p.ColorId=c.Id 
      LEFT JOIN ProductCategory pc ON p.ProductCategoryId=pc.Id 
      WHERE [email protected] AND r.DateReceived = @dateReceived"; 

    IList<PartReceipt> reportData; 
    using (DbConnection connection = ConnectionFactory.GetOpenConnection()) 
    { 
     reportData = 
     connection 
      .Query 
      <PartReceipt, Supplier, Part, ManufacturerPart, Manufacturer, Color, ProductCategory, PartReceipt>(
       sql, 
       (receipt, supp, part, mfgPart, mfg, color, productCategory) => 
       { 
        receipt.Supplier = supp; 
        receipt.Part = part; 
        receipt.Part.ManufacturerPart = mfgPart; 
        receipt.Part.ManufacturerPart.Parent = mfg; 
        receipt.Part.Color = color; 
        receipt.Part.ProductCategory = productCategory; 
        return receipt; 
       }, new { supplierId = supplier.Id, dateReceived }) 
      .ToList(); 
    } 
    return reportData; 
    }