C# 扩展 System.Data.Linq.DataContext
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1006653/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Extending System.Data.Linq.DataContext
提问by Kezzer
I have a class reflecting my dbml file which extends DataContext, but for some strange reason it's telling me
我有一个类反映了我的 dbml 文件,它扩展了 DataContext,但出于某种奇怪的原因,它告诉我
System.Data.Linq.DataContext' does not contain a constructor that takes '0' arguments"
System.Data.Linq.DataContext' 不包含采用 '0' 参数的构造函数"
I've followed various tutorials on this and haven't encountered this problem, and VS doesn't seem to able to fix it.
我已经遵循了有关此的各种教程,但没有遇到此问题,VS 似乎无法修复它。
Here's my implementation
这是我的实现
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Reflection;
using System.Text;
using IntranetMvcAreas.Areas.Accounts.Models;
namespace IntranetMvcAreas
{
partial class ContractsControlDataContext : DataContext
{
[FunctionAttribute(Name="dbo.procCC_Contract_Select")]
[ResultType(typeof(Contract))]
[ResultType(typeof(ContractCostCentre))]
[ResultType(typeof(tblCC_Contract_Data_Terminal))]
[ResultType(typeof(tblCC_CDT_Data_Service))]
[ResultType(typeof(tblCC_Data_Service))]
public IMultipleResults procCC_Contract_Select(
[Parameter(Name = "ContractID", DbType = "Int")] System.Nullable<int> ContractID,
[Parameter(Name = "ResponsibilityKey", DbType = "Int")] System.Nullable<int> ResponsibilityKey,
[Parameter(Name = "ExpenseType", DbType = "Char")] System.Nullable<char> ExpenseType,
[Parameter(Name = "SupplierID", DbType = "Int")] System.Nullable<int> SupplierID)
{
IExecuteResult result = this.ExecuteMethodCall(this, (MethodInfo)(MethodInfo.GetCurrentMethod()), ContractID, ResponsibilityKey, ExpenseType, SupplierID);
return (IMultipleResults)result.ReturnValue;
}
}
}
And it's ContractsControlDataContext
that's pointed at as the problem
这就是ContractsControlDataContext
问题所在
(btw, this has no relation to a very recent post I made, it's just I'm working on the same thing)
(顺便说一句,这与我最近发表的一篇文章无关,只是我在做同样的事情)
EDIT
编辑
It's probably worth clarifying this, so please read very carefully.
可能值得澄清这一点,所以请仔细阅读。
If you do notextend DataContext in the partial class, then ExecuteMethodCall
isn't accessible.
如果您不在分部类中扩展 DataContext,则ExecuteMethodCall
不可访问。
'Intranet.ContractsControlDataContext' does not contain a definition for 'ExecuteMethodCall' and no extension method 'ExecuteMethodCall' accepting a first argument of type 'Intranet.ContractsControlDataContext' could be found (are you missing a using directive or an assembly reference?)
“Intranet.ContractsControlDataContext”不包含“ExecuteMethodCall”的定义,并且找不到接受“Intranet.ContractsControlDataContext”类型的第一个参数的扩展方法“ExecuteMethodCall”(您是否缺少 using 指令或程序集引用?)
Maybe I'm missing something incredibly stupid?
也许我错过了一些非常愚蠢的东西?
SOLVED
解决了
I think perhaps Visual Studio struggled here, but I've relied entirely on auto-generated code. When right clicking on the database modeling language design view and hitting "View Code" it automagically creates a partial class for you within a specific namespace, however, this namespace was wrong. If someone could clarify this for me I would be most appreciative.
我想也许 Visual Studio 在这里挣扎,但我完全依赖于自动生成的代码。当右键单击数据库建模语言设计视图并点击“查看代码”时,它会自动在特定命名空间中为您创建一个分部类,但是,这个命名空间是错误的。如果有人能为我澄清这一点,我将不胜感激。
The .designer.cs file sits in namespace Intranet.Areas.Accounts.Models
, however the .cs file (partial class generated forthe .designer.cs file byVisual Studio) was in namespace Intranet
. Easy to spot for someone more experienced in this area than me.
该了.Designer.cs文件坐在namespace Intranet.Areas.Accounts.Models
,然而cs文件(生成的部分类为在了.Designer.cs文件通过Visual Studio中)是namespace Intranet
。很容易找到在这方面比我更有经验的人。
The real problem now is, who's answer do I mark as correct? Because many of you contributed to finding this issue.
现在真正的问题是,我将谁的答案标记为正确?因为你们中的许多人都为发现这个问题做出了贡献。
采纳答案by David Basarab
The object DataContext for linq does not have an empty constructor. Since it does not have an empty constructor you must pass one of the items it is excepting to the base.
linq 的对象 DataContext 没有空的构造函数。由于它没有空的构造函数,因此您必须将它排除的项目之一传递给基类。
From the MetaData for the DataContext.
来自 DataContext 的 MetaData。
// Summary:
// Initializes a new instance of the System.Data.Linq.DataContext class by referencing
// the connection used by the .NET Framework.
//
// Parameters:
// connection:
// The connection used by the .NET Framework.
public DataContext(IDbConnection connection);
//
// Summary:
// Initializes a new instance of the System.Data.Linq.DataContext class by referencing
// a file source.
//
// Parameters:
// fileOrServerOrConnection:
// This argument can be any one of the following: The name of a file where a
// SQL Server Express database resides. The name of a server where a database
// is present. In this case the provider uses the default database for a user.
// A complete connection string. LINQ to SQL just passes the string to the
// provider without modification.
public DataContext(string fileOrServerOrConnection);
//
// Summary:
// Initializes a new instance of the System.Data.Linq.DataContext class by referencing
// a connection and a mapping source.
//
// Parameters:
// connection:
// The connection used by the .NET Framework.
//
// mapping:
// The System.Data.Linq.Mapping.MappingSource.
public DataContext(IDbConnection connection, MappingSource mapping);
//
// Summary:
// Initializes a new instance of the System.Data.Linq.DataContext class by referencing
// a file source and a mapping source.
//
// Parameters:
// fileOrServerOrConnection:
// This argument can be any one of the following: The name of a file where a
// SQL Server Express database resides. The name of a server where a database
// is present. In this case the provider uses the default database for a user.
// A complete connection string. LINQ to SQL just passes the string to the
// provider without modification.
//
// mapping:
// The System.Data.Linq.Mapping.MappingSource.
public DataContext(string fileOrServerOrConnection, MappingSource mapping);
Something as simple as this would work. Any class that inherits from the DataConext must pass to the base constructor at least one of the types it is excepting.
像这样简单的事情会起作用。任何从 DataConext 继承的类都必须将至少一种它排除的类型传递给基本构造函数。
public class SomeClass : System.Data.Linq.DataContext
{
public SomeClass(string connectionString)
:base(connectionString)
{
}
}
回答by Marc Gravell
I'm assumingthat the namespace and (data-context) type name are correct... double check that first.
我假设命名空间和(数据上下文)类型名称是正确的...首先仔细检查一下。
It sounds to me like the codegen has failed, and so you only have yourhalf of the data-context (not the half that the IDE is meant to provide). There is a known bug in LINQ-to-SQL where this can fail if (as in your case) the using
declarations are above the namespace. No, I am not joking. Try changing the code:
这听起来好像在代码生成失败了,所以你只需要您的数据上下文(而不是一半的IDE是为了提供)的一半。LINQ-to-SQL 中存在一个已知错误,如果(如您的情况)using
声明位于命名空间之上,则此错误可能会失败。不,我不是在开玩笑。尝试更改代码:
namespace IntranetMvcAreas
{
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Reflection;
using System.Text;
using IntranetMvcAreas.Areas.Accounts.Models;
// the rest of your code
Now go into the designer, tweak something (for example, change the name of a property and change it back again) and hit save (this forces the codegen). Now see if it works.
现在进入设计器,调整一些东西(例如,更改属性的名称并再次更改)并点击保存(这会强制代码生成)。现在看看它是否有效。
回答by Kezzer
@Sander: I think you were on the right track. Instead of using a partial class and implementing the function for the sproc I instead followed this blogand used the *.designer.cs file for implementing it. Whilst I'm still experiencing problems with invalid type casting it did get rid of the original problem.
@Sander:我认为你在正确的轨道上。我没有使用分部类并为sproc实现该函数,而是按照此博客并使用 *.designer.cs 文件来实现它。虽然我仍然遇到无效类型转换的问题,但它确实摆脱了原始问题。
回答by mvr
David Basarab's answer is correct and should be marked as the answer.
David Basarab 的答案是正确的,应该标记为答案。
Your class is not providing any constructor, so a default constructor is provided. Default constructors for derived classes can only be provided if the base class has a parameterless constructor. However, the DataContext class which is your base class in this example does not provide a parameterless constructor. This explains the error message the compiler returned to you.
您的类没有提供任何构造函数,因此提供了一个默认构造函数。如果基类具有无参数构造函数,则只能提供派生类的默认构造函数。但是,在此示例中作为基类的 DataContext 类不提供无参数构造函数。这解释了编译器返回给您的错误消息。
Edit:
编辑:
Example:
例子:
class A {
public A(string s) {
}
}
class B : A {
}
An attempt to compile that returns an error in class B:
尝试编译返回 B 类错误:
'A' does not contain a constructor that takes '0' arguments
“A”不包含采用“0”参数的构造函数
回答by cdonner
The behavior of the generator regarding constructors is controlled, to some extent, by the Connection properties of the DBML. If Application Settings is True, and there is a settings property name, it will generate a constructor that reads the connection string from the Application Settings of the assembly. If there is a connection string, it will generate a constructor with a hardcoded connection string in the .designer.cs file. If there is neither, it will not generate a constructor without a connection string parameter, and you can safely provide a parameter-less constructor in a partial class without causing a conflict.
在某种程度上,生成器关于构造函数的行为由 DBML 的 Connection 属性控制。如果 Application Settings 为 True,并且有一个 settings 属性名称,它将生成一个构造函数,该构造函数从程序集的 Application Settings 中读取连接字符串。如果有连接字符串,它将在 .designer.cs 文件中生成一个带有硬编码连接字符串的构造函数。如果两者都没有,则不会生成没有连接字符串参数的构造函数,并且可以安全地在分部类中提供无参数构造函数而不会引起冲突。
These settings changes don't survive a round trip of the schema from the database, but I simply clear the connection settings from the properties after making changes and before I save the DBML.
这些设置更改不会在数据库模式的往返过程中保留下来,但我只是在进行更改之后和保存 DBML 之前从属性中清除连接设置。