Linq Query在选择整个表时返回null参数

时间:2015-07-01 10:35:10

标签: c# asp.net-mvc linq entity-framework

我对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

2 个答案:

答案 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
或者,即使最糟糕的是,该类被标记为密封,但这通常不会发生