none
'MSLinqToSQLGenerator': Generated code doesn't compile when using an entity namespace RRS feed

  • Question

  •  

    Hello,

     

    When I specify an "Entity Namespace" (ie: Test.Entities) for a linq to sql project item, the generated code doesn't compile:

     

    I did the following:

    - Create new solution

    - Add Class Library (named: 'Test')

    - Add New Item - LINQ to SQL Classes (named: 'DataClasses1.dbml')

    - Set 'Entity Namespace' to 'Test.Entities'

    - Drag and drop from Server Explorer the 'Person' table from my database.

     

    CREATE TABLE [dbo].[Person](

    [Id] [int] IDENTITY(1,1) NOT NULL,

    [FirstName] [varchar](50) NULL,

    [LastName] [varchar](50) NULL,

    [RowGuid] [uniqueidentifier] ROWGUIDCOL NOT NULL CONSTRAINT [DF_Person_RowGuid] DEFAULT (newid()),

    CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED

    (

    [Id] ASC

    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

    ) ON [PRIMARY]

     

    - Drag and drop from Server Explorer the 'Person_Update' stored procedure from my database.

     

    CREATE PROCEDURE [dbo].[Person_Update]

    (

    @Id int,

    @FirstName varchar(50),

    @LastName varchar(50),

    @RowGuid uniqueidentifier OUT

    )

    AS

    BEGIN

    DECLARE @NewRowGuid UNIQUEIDENTIFIER

    SET @NewRowGuid = NEWID()

    UPDATE "dbo"."Person"

    SET

    "FirstName" = @FirstName,

    "LastName" = @LastName,

    "RowGuid" = @NewRowGuid

    WHERE

    "Id" = @Id AND

    "RowGuid" = @RowGuid

    SET @RowGuid = @NewRowGuid

    END

     

    - Set the 'Default Method' for 'Update' to this stored procedure. (Use 'RowGuid (Original)' for the customization).

    - Save the DBML file.  

     

    The code generated by 'MSLinqToSQLGenerator' for the Update Method doesn't compile because the Entity is not found.

     

    'The type or namespace name 'Person' could not be found (are you missing a using directive or an assembly reference?)'

     

    private void UpdatePerson(Test.Entities.Person obj)

    {

    Person original = ((Person)(Persons.GetOriginalEntityState(obj)));

    System.Nullable<System.Guid> p1 = original.RowGuid;

    this.Person_Update(((System.Nullable<int>)(obj.Id)), obj.FirstName, obj.LastName, ref p1);

    original.RowGuid = p1.GetValueOrDefault();

    }

     

    The generated code should be:

     

    private void UpdatePerson(Test.Entities.Person obj)

    {

    Test.Entities.Person original = ((Test.Entities.Person)(Persons.GetOriginalEntityState(obj)));

    System.Nullable<System.Guid> p1 = original.RowGuid;

    this.Person_Update(((System.Nullable<int>)(obj.Id)), obj.FirstName, obj.LastName, ref p1);

    original.RowGuid = p1.GetValueOrDefault();

    }

     

    - Does a workaround exist? (But still be able to specify an Entity namespace)

     

    FYI: I have tested this on VS2008 RTM and VS2008 RTM SP1.

    Tuesday, August 26, 2008 11:29 AM

Answers

  • Coincidentally enough I ran across this same problem the week before last and we now have a bug filed for it.

    The only workaround I know of is copying those methods out into the non-generated datacontext and manually changing them then modifying the DBML/designer so it no longer tries to create the methods.

    Also be aware that concurrency checking with stored procedures fails silently when a change conflict occurs instead of raising exceptions so you might want to change them to dynamic or remove the concurrency check.

    [)amien
    Tuesday, August 26, 2008 4:24 PM
    Moderator

All replies

  • Coincidentally enough I ran across this same problem the week before last and we now have a bug filed for it.

    The only workaround I know of is copying those methods out into the non-generated datacontext and manually changing them then modifying the DBML/designer so it no longer tries to create the methods.

    Also be aware that concurrency checking with stored procedures fails silently when a change conflict occurs instead of raising exceptions so you might want to change them to dynamic or remove the concurrency check.

    [)amien
    Tuesday, August 26, 2008 4:24 PM
    Moderator
  • Thanks for your reply.

     

    I've managed to let the concurrency work by subclassing the context, then mark the StoredProcedure as 'virtual', and override it. Then I throw a concurrency exception myself.

     

    Not entirely happy with this approach, but in the end it works...

     

    Saturday, August 30, 2008 6:51 AM
  • Forgive me if I seem naive -- it's because I'm new to Windows development/C#/Visual Studio/LINQ.

     

    I think I'm bumping into this same bug.  I tried to use a custom tool namespace of "Foo.Bar" (say) for project named "Bar".  Originally, the only error I got was the "base(global::Bar.Properties.Settings..." -- "Bar" was undefined.  But, if I manually change the value of the SettingsObjectName attribute of the Connection element in the dbml, then I get the correct code generated in my C# (.designer.cs file), but then the compiler complains that Settings is undefined in Foo.Bar.Properties.

     

    Any advice?  The only real solution to this for me is likely going to be to un-nest my namespaces, which will have some unfortunate design consequences.

     

    thanks.

     

    Lane Wimberley

    Austin, TX

    Monday, September 8, 2008 10:13 PM
  • This isn't actually the same issue.

    SqlMetal/LINQ to SQL designer actually has it's own namespace properties which you are recommended to use instead of the Custom Tool Namespace.  The reason for this is that it allows two different namespaces - one for the context and the other for the entities.

    You can access these properties from the LINQ to SQL designer properties as "Context Namespace" and "Entity Namespace" respectively or set the attributes on the database tag in the DBML file directly. (Remember to set the custom tool namespace back to blank)

    [)amien
    Tuesday, September 9, 2008 7:00 AM
    Moderator