0

There's some issue with Entity Framework that doesn't call the 'Seed' method during a migration. With a considerable amount of effort, I've got it down to when it calls HistoryRepositor.GetLastModel (https://github.com/aspnet/EntityFramework6/blob/master/src/EntityFramework/Migrations/History/HistoryRepository.cs). In particular this section;

                    var baseQuery
                        = CreateHistoryQuery(context, contextKey)
                            .OrderByDescending(h => h.MigrationId);

                    var lastModel
                        = baseQuery
                            .Select(
                                s => new
                                    {
                                        s.MigrationId,
                                        s.Model,
                                        s.ProductVersion
                                    })
                            .FirstOrDefault();

'baseQuery' has a value as below.

{SELECT 
[Project1].[MigrationId] AS [MigrationId], 
[Project1].[ContextKey] AS [ContextKey], 
[Project1].[Model] AS [Model], 
[Project1].[ProductVersion] AS [ProductVersion]
FROM ( SELECT 
    [Extent1].[MigrationId] AS [MigrationId], 
    [Extent1].[ContextKey] AS [ContextKey], 
    [Extent1].[Model] AS [Model], 
    [Extent1].[ProductVersion] AS [ProductVersion]
    FROM [__MigrationHistory] AS [Extent1]
    WHERE [Extent1].[ContextKey] = @p__linq__0
)  AS [Project1]
ORDER BY [Project1].[MigrationId] DESC}

There are two records in the MigrationHistory table, which seems to be confirmed by using 'baseQuery.ToList()' in the immediate window and is in the correct order (MigrationId descending - these are timestamps so should be newest records first)

baseQuery.ToList()[0];
{System.Data.Entity.Migrations.History.HistoryRow}
ContextKey: "DT.DataAccess.AppContext"
MigrationId: "201612011150460_AutomaticMigration"
Model: {byte[5615]}
ProductVersion: "6.1.0-alpha1"

baseQuery.ToList()[1];
{System.Data.Entity.Migrations.History.HistoryRow}
ContextKey: "DT.DataAccess.AppContext"
MigrationId: "201611291632453_AutomaticMigration"
Model: {byte[5592]}
ProductVersion: "6.1.3-40302"

However, the record assigned to lastModel is not '201612011150460_AutomaticMigration' but rather '201611291632453_AutomaticMigration' which is unexpected.

lastModel = { MigrationId = "201611291632453_AutomaticMigration", Model = {byte[5592]}, ProductVersion = "6.1.3-40302" }

Using baseQuery.FirstOrDefault(); (or First()) from the Immediate window;

baseQuery.FirstOrDefault();
{System.Data.Entity.Migrations.History.HistoryRow}
ContextKey: "DT.DataAccess.AppContext"
MigrationId: "201611291632453_AutomaticMigration"
Model: {byte[5592]}
ProductVersion: "6.1.3-40302"

As baseQuery is created with OrderByDescending this should mean it's in a fixed order, correct?

MJF
  • 605
  • 5
  • 18
  • Do you try `var baseQuery = CreateHistoryQuery(context, contextKey) .OrderByDescending(h => h.MigrationId).First();` – Xurxo Garcia Dec 01 '16 at 13:08
  • This would be the equivalent of running `baseQuery.First()`? Running this (from the immediate window) returns the `201612011305419_AutomaticMigration` record. By separating the `lastModel` line, it looks like it's the `Select` statement that's the problem, returning only the other, older record rather than both. – MJF Dec 01 '16 at 13:28
  • 1
    Unless you add an `OrderBy` statement the order it returns the values is not guaranteed. Most of the time it will be the order you expect (usually the order data was entered into the table(s)), but it can change. `MigrationId` looks like it contains a date so you could order by that perhaps. – ChrisF Dec 01 '16 at 13:39
  • The `baseQuery` is created using `OrderByDescending(h => h.MigrationId)` as stated in the question, so this should mean that when used newer entries are listed first I'd have thought? – MJF Dec 01 '16 at 14:41
  • I agree with you that "it would be" the same but one works and the other doesn't, I guess for the reason that @ChrisF said, the order is not guaranteed. Maybe if `baseQuery` was a `List<>`, the order would be the expected. – Xurxo Garcia Dec 01 '16 at 14:53
  • 2
    @MJF - you are doing a `.Select` after the `.OrderBy` so could return the results in any order at that point. – ChrisF Dec 01 '16 at 14:58
  • I tried using the following after the Select statement `OrderByDescending(h => h.MigrationId).FirstOrDefault();`, however it still returns the older record. Also according to this then `Select` shouldn't affect the ordering? http://stackoverflow.com/questions/204505/preserving-order-with-linq – MJF Dec 01 '16 at 15:20

0 Answers0