Search code examples
c#entity-frameworklinqpad

Using extension method with LinQPad


I have a project that uses Entity Framework, code first. I would like to use LINQPad to seed my database.

To seed a database during the migration operation with Entity Framework I use the AddOrUpdate() extension method:

context.Rule.AddOrUpdate(
    y => y.Id,
    new Rule() { Id = Guid.Parse("b9b4fc65-fd0b-4f7f-aa27-3147c7665d27"), ... },
    new Rule() { Id = Guid.Parse("66d27186-8be4-4ce2-8a74-737576e7157b"), ... }
);

When I try to do the same with LINQPad I get an error:

Rules.AddOrUpdate(
    y => y.Id,
    new Rules() { Id = Guid.Parse("b9b4fc65-fd0b-4f7f-aa27-3147c7665d27"),  ... },
    new Rules() { Id = Guid.Parse("66d27186-8be4-4ce2-8a74-737576e7157b"), ... }
);

I get this error:

CS1929 'Table' does not contain a definition for 'AddOrUpdate' and the best extension method overload 'DbSetMigrationsExtensions.AddOrUpdate(IDbSet, params Rules[])' requires a receiver of type 'IDbSet'

Why doesn't LINQPad see this extension method? I have already added the NuGet reference to EntityFramework, and added all namespace in the NuGet package manager and namespace import of LINQPad.

I tried to write the same code like this:

System.Data.Entity.Migrations.DbSetMigrationsExtensions.AddOrUpdate(
        Rules as System.Data.Entity.IDbSet<Rules>,
        y => y.Id,
        new Rules() { Id = Guid.Parse("b9b4fc65-fd0b-4f7f-aa27-3147c7665d27"), ... },
        new Rules() { Id = Guid.Parse("66d27186-8be4-4ce2-8a74-737576e7157b"), ... }
);

But I get this error:

CS0039 Cannot convert type 'System.Data.Linq.Table<LINQPad.User.Rules>' to 'System.Data.Entity.IDbSet<LINQPad.User.Rules>' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion

So I guess the extension method is not working because the type of my Rules object is not correct. It seems LINQPad uses its own object type and I cannot convert it.


Solution

  • For starters, you should add System.Data.Entity.Migrations to the LINQPad query's namespace imports (press F4).

    Next, you are deluded by the AddOrUpdate method's signature. The first parameter is IDbSet<TEntity>, but that parameter is supplied automatically when you use it as extension method. In context.Rule.AddOrUpdate, it's context.Rule.

    If you don't have IDbSet<TEntity>, then you probably didn't connect to an EF6 DbContext.

    When using it in a regular static method call (just for academic purposes), it should be

    DbSetMigrationsExtensions.AddOrUpdate(context.Rule, y => y.Id, rules);
    

    (where rules, of course, is your collection of rules).

    By the way, you could also use context.Rule.AddOrUpdate(rules) because EF used the primary key by default.