【问题标题】:Calling Static Methods with Data Contexts in LINQPad在 LINQPad 中使用数据上下文调用静态方法
【发布时间】:2014-04-15 14:05:35
【问题描述】:

我正在使用 LINQPad 开发一种新的数据访问方法。在针对 MySchemaContext 中的表执行 LINQ-to-SQL 查询的方法中,我使用了一个参数,我使用静态方法从同一 DataContext 对象加载默认值。

当我在 LINQPad 中调用这个静态函数时(使用“C# 程序”设置)——从应用程序调用时工作正常,并且是公共的——我在分配返回的行上得到一个空引用异常静态函数的值到变量。如果我更改函数的逻辑,如果我不引用 MySchemaContext(例如,如果我手动组装 List 并返回它),它会起作用,但如果我引用 MySchemaContext,则会引发异常。

我的猜测是,这与 LINQPad 连接到我的数据库的方式有关 - 当从 LINQPad 调用库函数时 DataContext 无效,并且 GetTable<MyClassTable> 抛出空引用异常在图书馆。这是 LINQPad 的限制,还是我明显遗漏了什么?

这是我遇到问题的那种函数的示例。第一部分是我的库中的代码(我从 LINQPad 查询中调用):

namespace MyLibrary
{
 public class MyClass : MyClassTable
 {
   //There are reasons not to just add stuff to the partial class MyClassTable 
   //that aren't shown in this generic example

  public int MyClassTemplateID {get; set;}
  public int MyInt {get; set;}
  public string MyString {get; set;}

  public MyClass() {}
  public MyClass(int myClassTemplateID, int myInt, string myString) 
  {
   MyClassTemplateID = myClassTemplateID;
   MyInt = myInt;
   MyString = myString;
  }
  public static List<MyClass> GetMyClassesTemplate(int myClassTemplateID)
  {
   //MySchemaContext is a LINQ-to-SQL DataContext object, i.e., inherits from System.Data.Linq.DataContext 
   using (MySchemaContext myContext = new MySchemaContext())
   {
    return (from mct in myContext.GetTable<MyClassTable>().AsQueryable() 
     where mct.MyClassTemplateID == myClassTemplateID 
     select new MyClass
     {
      MyClassTemplateID = mct.MyClassTemplateID,
      MyInt = mct.MyInt,
      MyString = mct.MyString
     }).ToList<MyClass>();
   }
  }
 }
}

库函数在我的应用程序中运行良好。第二部分在我的 LINQPad 查询中,尝试调用相同的函数:

/*
    Call from LINQPad
    MyLibrary.dll is in "Additional References," and MyLibrary is in "Additional Namespace Imports."
*/

void Main()
{
 List<MyClass> myClassList = MyClass.GetMyClassesTemplate(1);
 //get error "NullReferenceException: Object reference not set to an instance of an object.
 //However, this exact line of code works fine in VisualStudio.
 //Have correct connection string for MySchemaContext in LINQPad.exe.config and lprun.exe.config
}

【问题讨论】:

  • using 块的内容分解成一堆不同的代码行,而不是试图一次完成整个事情。然后,您可能能够更仔细地缩小异常的实际原因,而不是猜测它。此外,请检查 myContext 以确保它不为空。很可能是这样。如果这是使用实体框架或其他东西,则可能 LINQPad 没有使用正确的连接字符串。
  • 您可能需要完全限定 MyClass 包括命名空间。 List&lt;MyClass&gt; myClassList = MyLibrary.MyClass.GetMyClassesTemplate(1);
  • 尝试将 GetMyclassTemplate(1) 的调用放在 try.. catch 块中并输出调用堆栈。我怀疑问题出在您的实际实现中,出于安全原因,您没有在此处复制。
  • 另一个想法,您可能需要注入连接字符串,因为在使用带有MySchemaContext myContext = new MySchemaContext()) 的 LinqPad 时无法从配置文件中获取它。
  • 您是否尝试将连接字符串放入 LINQPad.config(而不是 LINQpad.exe.config)?

标签: c# linq-to-sql linqpad


【解决方案1】:

我怀疑您的问题是使用了单独的命名空间。我能够使用以下代码访问 LINQPad 中的静态方法。 Nptice 特别是左括号和右括号的不匹配。

    void Main()
    {
        tName.test.DoIt(); // Fully qualify the static method name
    }

} // Close the generated context's class

namespace tName
{
    public class test
    {
    // Define other methods and classes here
        public static void DoIt()
        {
            Console.WriteLine("Done");
        }
    }
// } Don't close the namespace. Let LinqPad do it.

使用 LinqPad,您实际上是将您键入的代码注入到生成的上下文中。因此,您需要在注入新的命名空间/类之前假装它认为上下文的类已关闭。如果您不使用命名空间,则可以创建一个新类,但该类将是宿主类的子类,而不是直接位于相关命名空间下。我在blog post 中进一步讨论了这个问题。

【讨论】:

  • 抱歉,最好澄清一下:命名空间在我从 LINQPad 调用的代码中,根本不在 LINQPad 工作区中。请参阅上面的修改。
  • 从来没有相当解决了这个问题,但这个答案让我最接近我需要去的地方。
猜你喜欢
  • 1970-01-01
  • 2020-05-24
  • 1970-01-01
  • 2011-05-27
  • 2010-12-02
  • 1970-01-01
  • 1970-01-01
  • 2011-09-10
  • 1970-01-01
相关资源
最近更新 更多