在我的数据库中,特许权与公司有多对一的关系(每个特许权都有一个FirmID)。 SqlMetal捕获了这种关系并生成了适当的类,因此每个Concession都有一个Firm元素。我绑定了一个查询(简化为此处),该查询返回特许权列表以及相应公司的信息:
From c as Concession in Db.Concessions _
Select _
c.ConcessionID, _
c.Title, _
c.Firm.Title
问题在于,在某些情况下,特许权没有被分配给公司(c.FirmID为空),所以c.Firm什么都没有,我得到Object not set to an instance
等。
我可以通过以下方式进行连接来解决这个问题:
From c As Concession In Db.Concessions _
Join f As Firm In Db.Firms On f.FirmID Equals c.FirmID _
Select _
c.ConcessionID, _
c.Title, _
Firm_Title = f.Title
当FirmID为null(Firm_Title只是一个空字符串)时,这不会引发错误,但它不优雅:它不是面向对象的,并且它没有利用Linq to SQL所具有的所有关系智能已被捕获。
有没有更优雅的方式来处理这种情况?
答案 0 :(得分:3)
你在哪里得到错误?
我刚刚完成了类似的LINQ查询(在VB.Net中),并且工作正常(将Title设置为null)
您稍后将不得不处理标题为null,但这不是LINQ问题。 甚至可以在C#中轻松处理。
from c in Db.Concessions
select
{
c.ConcessionID,
c.Title,
Title = c.Firm.Title ?? ""
}
Vb.net中的等价物是使用Iif(),但我无法使用它。
答案 1 :(得分:2)
你的第二个例子是进行内部联接。它不会返回具有null FirmID的特许权。在这种情况下,您想要进行外连接:
http://msdn.microsoft.com/en-us/vbasic/bb737929.aspx#grpjoinleftout
答案 2 :(得分:1)
@James Curran:我在任何时候实际执行查询时都会收到错误 - 例如如果我将网格数据绑定到它,或者我将.ToList
应用于它。
VB.NET有一个新的真正的三元语法(仍然比C#更冗长)。这实际上有效:
From c As Concession In db.Concessions _
Select _
c.ConcessionID, _
c.Title, _
Firm_Title = If(c.Firm IsNot Nothing, c.Firm.Title, String.Empty) _
我对这种方法并不满意 - 对于我可能在外表中使用的每个字段都要做到这一点很痛苦。我很想知道为什么你的查询正在运行而我的查询没有 - 你的DataContext是由SqlMetal生成的吗?是从数据库中推断出的关系吗?
答案 3 :(得分:0)
他正在工作,因为他选择的是空字符串而不是空关系。
答案 4 :(得分:0)
在对象构造函数中处理它
Public Property office() As String
Get
Return _office
End Get
Set(ByVal value As String)
If value IsNot Nothing Then
_office = value
Else
_office = String.Empty
End If
End Set
End Property