【问题标题】:Non-Static method requires a target?非静态方法需要一个目标?
【发布时间】:2013-05-15 17:00:41
【问题描述】:

我以前从未见过这个错误,它非常令人困惑,我实际上是在尝试做一些事情,我说找到与传入的位置名称和类型匹配的所有位置(只会返回一个):

string name = columns[40];
Location type = db.Locations.Where(l => l.name == name).FirstOrDefault();
Location loc = db.Locations.Where(l => l.name == name && l.type == type.type).FirstOrDefault();

可能有更好的方法可以一举完成我想做的事情,但基本上我从列中获取名称(这来自 csv 文件),然后说,获取我的位置信息。在此之后,我说好了,现在我已经拥有了所有爵士乐,去给我找一个有这个名字和它的类型的位置。

但我得到了错误:

非静态方法需要一个目标

所有这些代码运行的顶级方法是:

static void Main(string[] args){}

本质上它只是一个控制台应用程序。那到底是怎么回事?

  • db 是上下文类,这应该很明显。
  • columns 是我从 csv 文件中提取数据,在这种情况下,columns[40] 类似于“纽约”

来自堆栈跟踪的完整错误消息: {“非静态方法需要一个目标。”}

注意:作为“可能的答案”发布的问题在这种情况下没有帮助,因为我运行此代码的主要方法是静态的。

经过进一步调查,我发现名称和类型为空,因此我进行了以下修复:

if (name != null)
{
    Location type = db.Locations.Where(l => l.name == name).FirstOrDefault();
    Location loc = db.Locations.Where(l => l.name == name && l.type == type.type).FirstOrDefault();
    locationNearbyId = loc.id;

    // More code
}

唉,我仍然收到错误:Location loc = db.Locations.Where(l => l.name == name && l.type == type.type).FirstOrDefault();

【问题讨论】:

  • 错误究竟在哪里? db 是什么? columns 是什么?
  • 你能发布完整的错误信息吗?它在谈论哪种非静态方法?在哪条线上?
  • 问题已更新,可能的答案对我没有帮助。请对此进行更多扩展。 @JonSkeet 请在回答之前阅读完整的问题
  • 第二个表达式中的nametype.type 是否恰好为空?

标签: linq


【解决方案1】:

我今天遇到了这种情况。来了解一下,我是这样做的:

Player player = db.Players
    .Where(p => p.ClubID == course.Club.ID && p.IsActive == true && p.Phone != null)
    .ToArray()
    .SingleOrDefault(p => p.Phone.FormatPhoneNumber() == phone);

course.Club 正在通过 EF 从我的数据库中延迟加载。起初,我以为我的问题是 FormatPhoneNumber 扩展,但后来发现删除 course.Club.ID 解决了这个问题:

int clubID = course.Club.ID;
Player player = db.Players
    .Where(p => p.ClubID == clubID && p.IsActive == true && p.Phone != null)
    .ToArray()
    .SingleOrDefault(p => p.Phone.FormatPhoneNumber() == phone);

因此,请避免在后续 LINQ 查询中使用从延迟加载的对象中收集的值 - 将它们分配给局部变量,然后在查询中使用这些变量。

【讨论】:

  • 很棒的解释!这是一个经常被遗忘的常见 Linq gotchya,通常我总是先将本地对象的属性评估为本地变量,然后再在 Linq 查询中使用它们,因为您永远不知道其他人何时会盲目地重构您的代码或重新生成您的数据类启用延迟加载。
【解决方案2】:

事实证明,因为名称和类型可以为空,所以必须在 if 语句旁边设置类型,因此我必须在继续之前检查类型和名称是否为空:

name = collumns[40];
type = db.Locations.Where(l => l.name == name).FirstOrDefault();

if (name != null && type != null)
{
    Location loc = db.Locations.Where(l => l.name == name && l.type == type.type).FirstOrDefault();

    //More code....
}

【讨论】:

  • 这似乎不太可能是原因,因为您给出的错误消息听起来确实是编译器错误。但后来你说你把它当作一个例外。不幸的是,由于您的问题非常模糊且不完整,因此很难帮助您或确定这个答案是否真的相关。
  • @JonSkeet 当您不知道它的含义时,该错误非常令人困惑。当使用从 linq 查询返回的变量时,我也遇到了这个错误(我的查询拉回了一个对象)。那个对象原来是null。一旦你知道它是一个空对象,它就很有意义。您正在调用没有目标的非静态方法 (type.type)(目标 type 为空)。这只是一个非常神秘的错误消息。
【解决方案3】:

事实上,问题是由于空的“类型”对象造成的。 我会这样解决:

var tType = type?.type;
Location loc = db.Locations.Where(l => l.name == name && (type != null && l.type == tType)).FirstOrDefault();

【讨论】:

    猜你喜欢
    • 2012-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    相关资源
    最近更新 更多