簡體   English   中英

LINQ查詢嘗試從列表對象傳遞列值時返回null

[英]Linq query returning null when trying to pass a column value from list object

當嘗試傳遞從列表對象獲取的列值時,Linq查詢返回null。 是否有可能像代碼中那樣做。 期待答案或一些建議。

var query = from p in context.ProcessStepTables
            where (p.DiagramID == diagramInfo.DiagramID)
            orderby p.ProcessNo select new{
                  DiagramProcessID = p.DiagramProcessID,
                  ProcessNo = p.ProcessNo,
                  ProcessID = p.ProcessID,
                  ProcessName = Process().Find(x => 
                           p.ProcessID == x.ProcessID).ProcessName.ToString(),
                  MakerName = Maker().Find(x=>
                           p.MakerID==x.MakerID).MakerName.ToString(),
                  Price = p.Price,
                  Note = p.Note,
                  Notice = p.Notice
            };

private List<MakerTable> Maker()
{
   List<MakerTable> pList = new List<MakerTable>();
   try
   {
       IQueryable<MakerTable> maker = (from data in context.MakerTables
                                       select data) as IQueryable<MakerTable>;
       foreach (MakerTable val in maker)
       {
          pList.Add(val);
       }
       return pList.OrderBy(x => x.MakerName).ToList();

    }
    catch (Exception ex)
    {
       MessageBox.Show(ex.Message);
       return null;
    }
}

這是因為您的提供程序不知道.ToString()方法,即,當您以IQueryable形式創建查詢時,它會轉換為等效的SQL查詢,因此,如果您包含任何C#函數,則會產生非原始數據類型,它將引發該錯誤,因為查詢的結構如下:

"Select s.DiagramProcessID as DiagramProcessID, ...other fields..
 from MakerTables s where something.ToString()=='anyvalue'"

所以很明顯,sql對.ToString()一無所知。

避免這種情況的一種簡單方法是,在對查詢應用.ToList()之后執行自定義Select。

當您執行該操作或.AsEnumerable() ,查詢將在數據庫上執行,並且現在無論自定義選擇或where子句都在CLR上翻譯

嘗試這個:

var query = context.ProcessStepTables
            .Where(s=>s.DiagramID == diagramInfo.DiagramID)
            .OrderBy(s=>s.ProcessNo)
            .ToList() //this will cause the query to be executed on the db
             //Now perform the selection on returned result set, now the linq
             //has to do with this dataset
            .Select(s=>new
             {
                   DiagramProcessID = s.DiagramProcessID,
                   ProcessNo = s.ProcessNo,
                   ProcessID = s.ProcessID,
                   //other items in your custom list
             });

而且您也可以將Maker方法替換為以下內容:

private List<MakerTable> Maker()
{
    try
    {
       return context.MakerTables.OrderBy(x=>x.MakerName).ToList();
    }
    catch (Exception ex)
    {
       MessageBox.Show(ex.Message);
       return null;
    }
}

分成幾步檢查是否為空,第一步是查詢,然后使用者需要檢查Marker是否包含有效值:

var query = from p in context.ProcessStepTables
            where (p.DiagramID == diagramInfo.DiagramID)
            orderby p.ProcessNo
            select new{
                        DiagramProcessID = p.DiagramProcessID,
                        ProcessNo = p.ProcessNo,
                        ProcessID = p.ProcessID,
                        ProcessName = Process().Find(x => p.ProcessID == x.ProcessID).ProcessName.ToString(),
                        Marker = context.MakerTables
                                        .OrderBy(itm => itm.MakerName)
                                        .FirstOrDefaut(itm => itm.MakerID==x.MakerID))
;

在某些情況下,找不到某事物,而該發現拋出異常。 最好先嘗試從Marker的屬性中提取值,然后再在Marker檢查上述代碼是否為null

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM