我对Linq很陌生,但最近一直在使用它并且一直在增长。我使用EF在MVC项目中通过Context访问我的数据库。
我想在这个例子中做的就是从我的一个表中获取所有数据。
var msgs = context.Messages.ToList();
我觉得这很好,但是当我以后使用这个列表时:
foreach(Message m in msgs)
{
var info = context.Contacts.Where(x => x.Id == m.recipient.Id)
.Select(x => x.MobileNumber).FirstOrDefault();
}
Message对象具有强制Recipient
,它是Contact对象(我数据库中的另一个实体)。
我在上面的行中得到NullArgumentException
,因为消息对象的Recipient参数在我的列表中为空,尽管它们在数据库中不为空。
奇怪的是列表大小合适,因此它进入了foreach循环。正确选择列表,但根据我的调试器,所有属性都为空。
我对此感到困惑:
console.WriteLine(context.Messages.Select(x => x.Recipient.FirstName).FirstOrDefault());
并将第一条消息的收件人的第一个名称写入控制台。因此,当我单独选择时,我可以检索邮件的收件人及其所有信息,但在尝试检索整个表并将其存储在列表中时,收件人对象为空。
就像我说的那样,我从包含上下文的MVC项目之外访问它。我正在从另一个项目中使用它。但是,这个其他项目包含对包含db的Message模型的MVC项目的引用,以及包含名为Message的不同类的另一个项目。这种含糊不清可能是问题的根源,还是我正在做的事情还有其他问题?
编辑我显然对我的问题造成了一些困惑。问题是,一旦我检索列表,列表的大小正确,但列表中消息对象的参数为空。例如,如果我写:
foreach (Message m in msgs)
{
Console.WriteLine("List Element Exists");
if (m.Recipient != null)
{
Console.WriteLine(m.Recipient.FirstName);
}
}
我得到了输出:
List Element Exists
List Element Exists
List Element Exists
List Element Exists
列表中的每个元素。
JK
答案 0 :(得分:1)
很可能在linq查询中where
条件的结果为空。
var info = context.Contacts.Where(x => x.Id == m.recipient.Id)
.Select(x => x.MobileNumber).FirstOrDefault()
此外,查询本身也存在一些问题,您可以编写相同的查询:
var mobileNumber = string.Empty; //if it is not a string then initialize with proper value
var info = context.Contacts.FirstOrDefault(x => x.Id == m.recipient.Id);
if(info != null)
mobileNumber = info.MobileNumber;
还有另一个问题;如果你执行这一行:
var msgs = context.Messages.ToList();
它将从DB获取所有Messages
;但你只需要一个电话号码。因此,不是获取所有记录,而是执行我提供的查询,而不是调用foreach。
修改
执行ToList()
时,立即执行db query;这意味着将不会加载Recipient
对象的Message
属性。根据您使用的是延迟加载还是预先加载,您需要另一种机制来获取Recipient
属性。喜欢的东西;
var msgs = context.Messages.Include(b => b.Recipients).ToList();
答案 1 :(得分:1)
如果您希望msg.Recipient包含某些内容(即在数据库上编译数据),那么它就是一个映射问题。最常见的问题是收件人属性未标记为虚拟。
EDIT
或者,即使最糟糕的是,该类被标记为密封,但这通常不会发生