views:

2960

answers:

5

I have a class reflecting my dbml file which extends DataContext, but for some strange reason it's telling me

System.Data.Linq.DataContext' does not contain a constructor that takes '0' arguments"

I've followed various tutorials on this and haven't encountered this problem, and VS doesn't seem to able to fix it.

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

(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 not extend DataContext in the partial class, then ExecuteMethodCall isn't accessible.

'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?)

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.

The .designer.cs file sits in namespace Intranet.Areas.Accounts.Models, however the .cs file (partial class generated for the .designer.cs file by Visual Studio) was in namespace Intranet. Easy to spot for someone more experienced in this area than me.

The real problem now is, who's answer do I mark as correct? Because many of you contributed to finding this issue.

+3  A: 

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.

From the MetaData for the DataContext.

// 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.

public class SomeClass : System.Data.Linq.DataContext
{
    public SomeClass(string connectionString)
        :base(connectionString)
    {

    }
}
David Basarab
But they're concrete? They should be inherited regardless and not have to be implemented?
Kezzer
+4  A: 

I'm assuming that 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 your half 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:

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.

Marc Gravell
Indeed, it is almost certain to be this. One should never have the using statements outside the namespace in the DBML's code-behind file.
Sander
After I did that I tried a rebuild and on top of the error I stated I was additionally greeted by "Error 2 Metadata file 'D:\WEB\IntranetMvcAreas\IntranetMvcAreas\bin\IntranetMvcAreas.dll' could not be found IntranetMvcAreas.Tests"
Kezzer
That is simply that your unit tests isn't going to be happy until the core dll builds... so I don't think that tells us anything
Marc Gravell
I'd also found this: http://blog.paulgeorge.co.uk/2008/12/07/silverlight-and-linq-problems-yourdataclassesdatacontext-does-not-contain-a-constructor-that-takes-0-arguments/ but the function was already defined. Still clueless. I re-created the dbml from scratch and still get the same error.
Kezzer
Perhaps try recreating it without your extra file in existence (rename it and exclude it from the project)
Marc Gravell
Yeah, no luck at all really. I've tried everything I can think of, completely deleting the classes out, re-including them, including them with a different name etc. and nothing is happening. Guess I won't be able to get data out of my database :)
Kezzer
Ooh, just thinking, I'm using Phil Haack's areas lib located here: http://haacked.com/archive/2008/11/04/areas-in-aspnetmvc.aspx Perhaps this is why problems are occurring?
Kezzer
A: 

@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 blog and 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.

Kezzer
You edited the .designer.cs? That is a very bad idea... your code may disappear at any time.
Marc Gravell
As I found out, but I did it out of desperation as opposed to pure will. Don't worry, I found out the hard way that you shouldn't edit the designer.cs otherwise all hell breaks loose.
Kezzer
+2  A: 

David Basarab's answer is correct and should be marked as the answer.

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.

Edit:

Example:

class A {
    public A(string s) {
    }
}

class B : A {
}

An attempt to compile that returns an error in class B:

'A' does not contain a constructor that takes '0' arguments

mvr
The constructors are implemented in the .designer.cs file, I'm using the partial class for implementing my function. If I use the partial class it fails to compile, if I don't use it, it compiles fine. In both cases the constructors are implemented. A partial class shouldn't cause it to fail because upon compile it should bring in the already defined constructors.
Kezzer
What is the name of the partial class that exists in the designer.cs file?
mvr
You may indeed be correct sir. Just check my edit in my original post, you've probably got a better idea than me with this one :)
Kezzer
Just remember that if you have a partial class in one file FileA.cs, and you want to add extra information to that class in a partial class in another file FileB.cs, then the partial class you declare in FileB.cs must have the same name as the one in FileA.cs.On the namespace issue, I think you can customise which namespace LINQ to SQL uses when it generates its classes. There should be a property in the designer. (I use Entity Framework so I'm working from memory here.)I still feel you should mark David's answer as correct, because he did diagnose the source of the error message first.
mvr
Agreed. Well I'm working with LINQ for the current moment, but I have no idea what the support is like for multiple shapes using the entity framework. Cheers.
Kezzer
A: 

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.

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.

cdonner