FNH和NH的新功能。通過LEFT OUTER JOIN進行的大型一對多選擇查詢優化
我想優化OneToMany映射的查詢。我實際上只希望檢索Segment = 0中的一個。PlantID,AreaID,CellID,DeviceID,StartDateTime組成了Data的複合主鍵。將分段添加到DataMore1和DataMore2的組合鍵。
一個事件可以記錄多達400個數據點...取決於他們選擇的選項。 因此,我們選擇將數據存儲在單獨的表格中,以便在x天或數月後清除不需要的數據。
目標是通過FluentNHibernate做這樣的事情。
SELECT Data.PlantID, Data.AreaID, Data.CellID, Data.DeviceID, Data.StartDateTime, Data.DataPoint01, DataMore1.Segment, DataMore1.DataPoint101,
DataMore2.DataPoint201
FROM Data
LEFT OUTER JOIN
DataMore1 ON Data.PlantID = DataMore1.PlantID AND Data.AreaID = DataMore1.AreaID AND Data.CellID = DataMore1.CellID AND
Data.DeviceID = DataMore1.DeviceID AND Data.StartDateTime = DataMore1.StartDateTime AND **DataMore1.Segment = 0**
LEFT OUTER JOIN
DataMore2 ON Data.PlantID = DataMore2.PlantID AND Data.AreaID = DataMore2.AreaID AND Data.CellID = DataMore2.CellID AND
Data.DeviceID = DataMore2.DeviceID AND Data.StartDateTime = DataMore2.StartDateTime AND **DataMore2.Segment = 0**
模型
public class Data
{
public virtual int PlantID { get; set; }
public virtual int AreaID { get; set; }
public virtual int CellID { get; set; }
public virtual int DeviceID { get; set; }
public virtual DateTime StartDateTime { get; set; }
public virtual float DataPoint01 { get; set; }
public virtual float DataPoint02 { get; set; }
public virtual float DataPoint99 { get; set; }
public virtual IEnumerable<DataMore1> DataMore1 { get; set; }
public virtual IEnumerable<DataMore2> DataMore2 { get; set; }
}
public class DataMore1
{
public virtual int PlantID { get; set; }
public virtual int AreaID { get; set; }
public virtual int CellID { get; set; }
public virtual int DeviceID { get; set; }
public virtual DateTime StartDateTime { get; set; }
public virtual byte Segment { get; set; }
public virtual float DataPoint101 { get; set; }
public virtual float DataPoint102 { get; set; }
public virtual float DataPoint199 { get; set;}
}
public class DataMore2
{
public virtual int PlantID { get; set; }
public virtual int AreaID { get; set; }
public virtual int CellID { get; set; }
public virtual int DeviceID { get; set; }
public virtual DateTime StartDateTime { get; set; }
public virtual byte Segment { get; set; }
public virtual float DataPoint201 { get; set; }
public virtual float DataPoint202 { get; set; }
public virtual float DataPoint299 { get; set; }
}
而映射
public DataMap()
{
Table("Data");
CompositeId()
.KeyProperty(e => e.PlantID)
.KeyProperty(e => e.AreaID)
.KeyProperty(e => e.CellID)
.KeyProperty(e => e.DeviceID)
.KeyProperty(e => e.StartDateTime);
Map(e => e.DataPoint01);
Map(e => e.DataPoint02);
Map(e => e.DataPoint99);
HasMany(e => e.DataMore1)
.KeyColumns.Add("PlantID")
.KeyColumns.Add("AreaID")
.KeyColumns.Add("CellID")
.KeyColumns.Add("DeviceID")
.KeyColumns.Add("StartDateTime")
.Cascade.All().Inverse();
HasMany(e => e.DataMore2)
.KeyColumns.Add("PlantID")
.KeyColumns.Add("AreaID")
.KeyColumns.Add("CellID")
.KeyColumns.Add("DeviceID")
.KeyColumns.Add("StartDateTime")
.Cascade.All().Inverse();
}
public DataMore1Map()
{
Table("DataMore1");
CompositeId()
.KeyProperty(e => e.PlantID)
.KeyProperty(e => e.AreaID)
.KeyProperty(e => e.CellID)
.KeyProperty(e => e.DeviceID)
.KeyProperty(e => e.StartDateTime)
.KeyProperty(e => e.Segment);
Map(e => e.DataPoint101);
Map(e => e.DataPoint102);
Map(e => e.DataPoint199);
}
public DataMore2Map()
{
Table("DataMore2");
CompositeId()
.KeyProperty(e => e.PlantID)
.KeyProperty(e => e.AreaID)
.KeyProperty(e => e.CellID)
.KeyProperty(e => e.DeviceID)
.KeyProperty(e => e.StartDateTime)
.KeyProperty(e => e.Segment);
Map(e => e.DataPoint201);
Map(e => e.DataPoint202);
Map(e => e.DataPoint299);
}
太棒了!現在我有一個線索如何前進。我希望將選擇減少到單個選擇語句。我期待着放棄這一點。 – faldeland
在運行時獲取InvalidOperationException ...從範圍''引用類型爲'MyType'的變量'p',但未定義 – faldeland
我添加了新答案後能夠獲得過去的「未定義」錯誤。現在我得到一個運行時錯誤,dm1和dm2爲空。有什麼想法嗎? – faldeland