1

I am trying to build the PostgreSqlGeneration code from this repository on Mono. Unfortunately I get an error I do not understand.

In the PostgreSqlMigrationSqlGenerator class the following method gives the build error "delegate System.Action does not take `1' arguments":

private void GenerateStatements(IEnumerable<MigrationOperation> migrationOperations)
{

    Check.NotNull(migrationOperations, "migrationOperations");
    DetectHistoryRebuild(migrationOperations).Each<dynamic>(o => Generate(o)); // <=here!

}

/edit The signature of the extension method is as follows:

Signatures and error

/edit 2. Here is the declaration for Generate method:

private void Generate(HistoryOperation migration)
{
    //migration

    Check.NotNull(migration, "historyOperation");

    using (var writer = Writer())
    {
        migration.CommandTrees.Each(
            commandTree =>
            {

                switch (commandTree.CommandTreeKind)
                {
                    case DbCommandTreeKind.Insert:


                        writer.Write(GetInsertHistorySql((DbInsertCommandTree)commandTree));

                       break;
                }
            });

        Statement(writer);
    }

}

I do not know why that happens since the Each only has a dynamic type and no integer one. But I am not that experienced with such lambda expressions. To learn more and to get the migrations to work I hope someone can explain why the error happens and how it can be fixed.

Patrick Hofman
  • 153,850
  • 22
  • 249
  • 325
user2609980
  • 10,264
  • 15
  • 74
  • 143

2 Answers2

1

Disclaimer: I feel really bad that I cannot find anything that explains why this isn't working. If someone knows; please tell me. Google has failed here.

Clearly the compiler is picking the wrong overload for Each. There are two in the library, one that takes an Action<T> and another that takes an Action<T, int>.

If you weren't using dynamic it would work fine (if I had to guess); but dynamic causes all sorts of weird issues; plus you are using Mono.

Since the compiler insists you use the other overload, the solution is simple enough. Just use it!

DetectHistoryRebuild(migrationOperations).Each<dynamic>((o, i) => Generate(o));

You took an extra parameter and didn't use it. Its not the end of the world.

You could also just explicitly instantiate the Action so the compiler doesn't have to choose:

DetectHistoryRebuild(migrationOperations).Each<dynamic>(new Action(o => Generate(o)));
BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117
  • Thanks. Now the error (on the same line) is `Delegate System.Func does not take \`2' arguments`... – user2609980 Nov 21 '14 at 19:27
  • @user2609980 Wow; sucks to be you. Please try my new suggestion and directly instantiate the action. – BradleyDotNET Nov 21 '14 at 19:30
  • @user2609980 It should be `Each((o, i) => ...)`. There are two overloads for `Each` with one generic parameter. The one with two generic parameters is an overload you're not interested in. –  Nov 21 '14 at 19:30
  • @hvd I agree; except that doesn't seem to be working. – BradleyDotNET Nov 21 '14 at 19:31
  • @BradleyDotNET No, `Each((o, i) => ...)` is not the `Each(o => ...)` the OP is using in the question. :) –  Nov 21 '14 at 19:32
  • Ha guys I changed it to (0, i) and now it says: `Dynamic operation cannot be compiled without Microsoft.Csharp.dll assembly reference`! – user2609980 Nov 21 '14 at 19:33
  • @hvd I realize that. The OPs problem is that the compiler appears to be selecting the two argument overload *even though he passed it a one argument function*. Like I said, I can't figure out why it would do that. I suggested this as a *workaround*. – BradleyDotNET Nov 21 '14 at 19:34
  • Okay adding the reference made the code work. Unfortunately the next error is `System.NotImplementedException: MARS is not yet implemented.` Now I have to see how to put that off? :/ – user2609980 Nov 21 '14 at 19:34
  • @BradleyDotNET My point is that `Each` cannot *ever* select the `Action` overload because the *only* `Each` there is takes a `Func`. –  Nov 21 '14 at 19:35
  • 1
    @user2609980 Heh, I guess that's an improvement, that's completely unrelated to your current question, at any rate. :) –  Nov 21 '14 at 19:37
  • @hvd Ummm... that should match Action which is the overload above the intended one. Am I just reading the picture wrong? – BradleyDotNET Nov 21 '14 at 19:39
  • Thank you for your help! I see now that I did not yet implement this new `PostgreSqlMigrationSqlGenerator`. I have now and will let you known what happens. – user2609980 Nov 21 '14 at 19:42
  • @BradleyDotNET There are three overloads in total. (I'll ignore the `this` parameter.) `Each(Action)`, which has one generic parameter. `Each(Action)`, which also has one generic parameter. `Each(Func)`, which has two generic parameters. The OP wants the second overload, and you're attempting to help give the OP the first overload. Both the second and the first overload are specified by `Each`. Only the third overload can be specified by `Each`. –  Nov 21 '14 at 19:42
  • @hvd Oh *thats* what you were referring to. Okay; we're good now. I fixed the code. Thanks for pointing that out! Sorry for my blindness this morning. – BradleyDotNET Nov 21 '14 at 19:44
  • No worries guys. New problem posted here: http://stackoverflow.com/questions/27069403/how-to-circumvent-mars-is-not-yet-implemented-exception. – user2609980 Nov 21 '14 at 20:08
0

The solution was to add a missing assembly reference of Microsoft.Csharp.dll. For some reason the error of a missing assembly reference became visible after changing the lambda signature from i to (i,j) as suggested by BradleyDotNET in his answer.

user2609980
  • 10,264
  • 15
  • 74
  • 143