Vb.net 如何在LINQ子查询中处理Null?

Vb.net 如何在LINQ子查询中处理Null?,vb.net,linq,linq-to-sql,null,Vb.net,Linq,Linq To Sql,Null,我有一个子查询,它返回子表中最近的值。在某些情况下,子查询不返回任何内容。以下查询在运行时失败,因为推断的MemberPrice类型是decimal,并且不可为null 简化查询: Dim q = From s In dc.STOCKs _ Select s.ID, MemberPrice = _ (From mp In dc.STOCKPRICEs Where mp.NUMBER = s.NUMBER _ Order By dc.date

我有一个子查询,它返回子表中最近的值。在某些情况下,子查询不返回任何内容。以下查询在运行时失败,因为推断的MemberPrice类型是decimal,并且不可为null

简化查询:

Dim q = From s In dc.STOCKs _
        Select s.ID, MemberPrice = _
          (From mp In dc.STOCKPRICEs Where mp.NUMBER = s.NUMBER _
          Order By dc.date Descending _
          Select mp.PRICE).FirstOrDefault
在SQL中,子查询将包含Top(1),并在为空时返回Null。在LINQ我该怎么处理?有没有办法使MemberPrice为空,或者如果找不到,将默认值设置为零(或者更优雅的解决方案)

非常感谢,斯图尔特,斯图尔特,试试这个:

Dim q = From s In dc.STOCKs _
    Select s.ID, MemberPrice = _
      if((From mp In dc.STOCKPRICEs Where mp.NUMBER = s.NUMBER _
      Order By dc.date Descending _
      Select mp.PRICE).FirstOrDefault),0)

空合并运算符将强制MemberPrice的空值为零。

DefaultIfEmpty扩展方法是否满足您的要求?

Stuart

我就是这样让它在我的机器上工作的。我为它在c#道歉;我已经很久没有用VB了

注意在“select”语句中使用了“new”运算符,在FirstOrDefault()之后使用了null合并运算符

斯图尔特

我将数据库中的Price字段更改为不允许空值,并得到与您相同的错误:

"Operator '??' cannot be applied to operands of type 'decimal' and 'int'". 
正如您所指出的,当Price设置为不允许数据库中出现null时,null合并操作符不再工作,因为它希望看到一个可为null的decimal类型:

decimal?
如果我删除空合并操作符并运行不包含价格的测试用例,我会得到:

"The null value cannot be assigned to a member with type System.Decimal which is a non-nullable value type.."
下面是有效的代码。我将子查询结果转换为十进制?在应用null合并运算符之前

public class Class1
{

    DataClasses1DataContext dc = new DataClasses1DataContext();

    public decimal test(int stockID)
    {

        var q = from s in dc.Stocks
                where s.StockID == stockID
                select new
                {
                    StockID = s.StockID,
                    memberPrice = ((decimal?)(from mp in dc.StockPrices
                                   where mp.StockID == s.StockID
                                   select mp.Price).FirstOrDefault()) ?? 0
                };

        return q.FirstOrDefault().memberPrice;
    }
}

你能定义你所说的失败是什么意思吗?如果子查询为空,则FirstOrDefault应不返回任何内容,因此在这种情况下MemberPrice应为0。我得到一个System.InvalidOperationException{“无法将空值分配给System.Decimal类型的成员,该类型的值不可为空。”}。我还希望如果为null,它会返回0,所以我一定是遗漏了什么。mp.PRICE的类型是什么?@Stuar,你得到解决方案了吗?因为我也有同样的问题。@Vikas,是的,Roberts下面的答案就是答案。强制转换为可为null的类型解决了我一直遇到的一系列问题。null合并操作符??vb.netYes中不存在它存在:If函数。正如在If(possibleNullValue,valueIfNull)@Robert中一样,我编辑了代码示例以使用VB.Net版本的合并运算符。我得到了以下编译器错误:“二进制'If'表达式中的第一个操作数必须为Null或引用类型。”我得到了相同的编译器错误,因为MemberPrice被推断为值类型(decimal).我曾将其用于平面外部联接,但无法解决如何避免为mp.Price decimal值类型分配任何内容。你对我可能尝试的语法有什么想法吗?我在C#中遇到了与此代码相同的编译器错误,因为memberPrice被推断为十进制(vs Nullable)。错误是“运算符”??“不能应用于“decimal”和“int”类型的操作数。您机器上的价格类型是什么?我机器上的价格类型是十进制(18,0)允许为空。Robert,非常感谢您为解决此问题所做的努力。
public class Class1
{

    DataClasses1DataContext dc = new DataClasses1DataContext();

    public decimal test(int stockID)
    {

        var q = from s in dc.Stocks
                where s.StockID == stockID
                select new
                {
                    StockID = s.StockID,
                    memberPrice = ((decimal?)(from mp in dc.StockPrices
                                   where mp.StockID == s.StockID
                                   select mp.Price).FirstOrDefault()) ?? 0
                };

        return q.FirstOrDefault().memberPrice;
    }
}