4

Closed

Code first stored procedure mapping fails when the stored procedures have more than 25 parameter mappings

description

Hi,

This is a bit of a show stopper for me and I'm sure others when they discover it. I don't know if it's a regression as I have only recently started using EF in this new app and need/want to use the new code first stored procedure mapping capability. I got stuck when I was getting model errors such as:

Schema specified is not valid. Errors:
(100,14) : error 2037: The function parameter xxxxx is not defined in the function yyyy_Insert.
(95,12) : error 2037: A mapping function bindings specifies a function CodeFirstDatabaseSchema.yyyy_Insert but does not map the following function parameters: zzzzz, wwww, ...

I got these errors when I added a new class to my model which currently has around 20 classes. Initially I thought it was related to my TPT and limitations with EF 6 and the stored procedure mapping so to check I knocked up a simple app with several classes in a TPT hierarchy and the app to my surprise worked - generating the correct tables and stored procedures. I was pretty sure it had something to do with mapping the stored procedure parameters to alternate names so I changed the name of the SPs for one entity and added an explicit mapping for one parameter. Again the test app worked fine.

It then dawned on me that the new class I was adding to my real model had quite a few properties so I added a whole bunch to the class in my test app that had the SP parameter mapping and bingo I was able to reproduce the problem.

With further investigation I found it is actually nothing to do wit the TPT model but only the combination of using stored procedure mapping AND explicit parameter mapping AND the POCO class has more than 26 properties it seems.

E.g. using this POCO
public class Vehicle2
{
    public Int32 Id { get; set; }
    public Int32 Value1 { get; set; }
    public Int32 Value2 { get; set; }
    public Int32 Value3 { get; set; }
    public Int32 Value4 { get; set; }
    public Int32 Value5 { get; set; }
    public Int32 Value6 { get; set; }
    public Int32 Value7 { get; set; }
    public Int32 Value8 { get; set; }
    public Int32 Value9 { get; set; }
    public Int32 Value10 { get; set; }
    public Int32 Value11 { get; set; }
    public Int32 Value12 { get; set; }
    public Int32 Value13 { get; set; }
    public Int32 Value14 { get; set; }
    public Int32 Value15 { get; set; }
    public Int32 Value16 { get; set; }
    public Int32 Value17 { get; set; }
    public Int32 Value18 { get; set; }
    public Int32 Value19 { get; set; }
    public Int32 Value20 { get; set; }
    public Int32 Value21 { get; set; }
    public Int32 Value22 { get; set; }
    public Int32 Value23 { get; set; }
    public Int32 Value24 { get; set; }
    public Int32 Value25 { get; set; }  // works ok with or without SP explicit parameter mapping
    public Int32 Value26 { get; set; }  // doesn't work from here on if SPs have explicit parameter mapping defined
 //   public Int32 Value27 { get; set; }
 //   public Int32 Value28 { get; set; }
 //   public Int32 Value29 { get; set; }
}
with this configuration
        modelBuilder.Entity<Vehicle2>().ToTable("Vehicle2").MapToStoredProcedures(s =>
            s.Insert(i => i.HasName("MyVehicle2Insert")
                   .Parameter(p => p.Value1, "AnotherValue1")  // When commented out works fine
                )
            .Update(u => u.HasName("MyVehicle2Update")
                    .Parameter(p => p.Value1, "AnotherValue2")  // When commented out works fine
                )
            .Delete(d => d.HasName("MyVehicle2Delete"))
            );
You will get the problem. If you reduce the number of properties by commenting out Value26 it will however work. Likewise if you leave in Value26 but comment out the explicit parameter mapping for the stored procedures it will also work.

I've attached my test project which clearly demonstrates the problem.

Thanks,
Norm.

file attachments

Closed Nov 6, 2013 at 8:28 PM by maumar

comments

glennc wrote Oct 11, 2013 at 6:17 PM

EF Team Triage: Assigning to an EF Team member to investigate.

maumar wrote Oct 11, 2013 at 9:58 PM

I was able to reproduce the issue. This reproes for 26+ properties because we create IdentityDictionary for MetadataCollection for item with 26 properties and more (for perf reason). IdentityDictionary is build before we conduct the rename of the stored proc parameter and it does not get modified/invalidated after we perform the rename, so it contains stale data and hence the validation issues.

maumar wrote Oct 11, 2013 at 9:59 PM

This is a legitimate EF6 bug - reassigning for triage.

divega wrote Nov 4, 2013 at 11:10 PM

Changing title to reflect that this happens when the stored procedure has over 25 parameters.

maumar wrote Nov 6, 2013 at 8:28 PM

fixed by emil in c5f4416b97d796b7aa800fcc1d320558a01c55db

maumar wrote Nov 6, 2013 at 8:30 PM

verified - run all our tests with IdentityDictionary being always created to catch any other potential issues in this area