0

I'm trying to reduce the amount of code in my application.

I want to turn this

 return _db.SnapshotQueues
               .Include(c => c.SnapshotDefinition)
               .Include(c => c.SnapshotDefinition.Client)
               .Include(c => c.Server)
               .Select(s => new SnapshotQueueModel()
               {
                   SnapshotQueueID = s.SnapshotQueueID,
                   SnapshotDefinitionID = s.SnapshotDefinitionID,
                   ScheduleID = s.ScheduleID,
                   DateCreated = s.DateCreated,
                   Protected = s.Protected,
                   StartTime = s.StartTime,
                   FinishTime = s.FinishTime,
                   Processed = s.Processed,
                   CoreSnapshotDatabaseName = s.CoreSnapshotDatabaseName,
                   Removed = s.Removed,
                   SnapshotID = s.SnapshotID,
                   EmailNotification = s.EmailNotification,
                   Email = s.Email,
                   ServerID = s.ServerID,
                   DateRequested = s.DateRequested,
                   Canceled = s.Canceled,
                   Active = s.Active,
                   LastSnapshotQueueActionID = s.SnapshotQueueActions.OrderByDescending(o => o.ActionDate).ThenByDescending(o => o.SnapshotQueueActionID).FirstOrDefault().ActionID,
                   LastAction = s.SnapshotQueueActions.OrderByDescending(o => o.ActionDate).ThenByDescending(o => o.SnapshotQueueActionID).FirstOrDefault().SnapshotAction.Description,
                   SnapshotLogCount = s.SnapshotGenerationLogs.Count(),

                   SnapshotDefinition = s.SnapshotDefinition.Name,
                   Server = s.Server.ServerName,
                   ScheduleName = s.Schedule.Name,
                   ClientName = s.SnapshotDefinition.Client.ClientName_Long
               }
               )
               .Where(s => s.SnapshotDefinitionID == snapshotDefinitionID)
               .OrderBy(sortFieldExpression);

into this

 return _db.SnapshotQueues
               .Include(c => c.SnapshotDefinition)
               .Include(c => c.SnapshotDefinition.Client)
               .Include(c => c.Server)
               .Select(s => _snapshotQueueModelGet(s))
               .Where(s => s.SnapshotDefinitionID == snapshotDefinitionID)
               .OrderBy(sortFieldExpression);

        private readonly Func<SnapshotQueue, SnapshotQueueModel> _snapshotQueueModelGet = s => new SnapshotQueueModel
        {
            SnapshotQueueID = s.SnapshotQueueID,
            SnapshotDefinitionID = s.SnapshotDefinitionID,
            ScheduleID = s.ScheduleID,
            DateCreated = s.DateCreated,
            Protected = s.Protected,
            StartTime = s.StartTime,
            FinishTime = s.FinishTime,
            Processed = s.Processed,
            CoreSnapshotDatabaseName = s.CoreSnapshotDatabaseName,
            Removed = s.Removed,
            SnapshotID = s.SnapshotID,
            EmailNotification = s.EmailNotification,
            Email = s.Email,
            ServerID = s.ServerID,
            DateRequested = s.DateRequested,
            Canceled = s.Canceled,
            Active = s.Active,
            LastSnapshotQueueActionID =
                s.SnapshotQueueActions.OrderByDescending(o => o.ActionDate)
                    .ThenByDescending(o => o.SnapshotQueueActionID)
                    .FirstOrDefault()
                    .ActionID,
            LastAction =
                s.SnapshotQueueActions.OrderByDescending(o => o.ActionDate)
                    .ThenByDescending(o => o.SnapshotQueueActionID)
                    .FirstOrDefault()
                    .SnapshotAction.Description,
            SnapshotLogCount = s.SnapshotGenerationLogs.Count(),
            SnapshotDefinition = s.SnapshotDefinition.Name,
            Server = s.Server.ServerName,
            ScheduleName = s.Schedule.Name,
            ClientName = s.SnapshotDefinition.Client.ClientName_Long
        };

The problem is that it passes in to SQL Server, and the database doesn't know what to do with the function. I get the error

The LINQ expression node type 'Invoke' is not supported in LINQ to Entities.

I'm using the same select list in a few places, so it would stop bugs creeping in when field are added.

1 Answer 1

2

Declare your field as Expression<Func<SnapshotQueue, SnapshotQueueModel>>:

private readonly Expression<Func<SnapshotQueue, SnapshotQueueModel>> _snapshotQueueModelGet = s => new SnapshotQueueModel
{
    SnapshotQueueID = s.SnapshotQueueID,
    SnapshotDefinitionID = s.SnapshotDefinitionID,
    ScheduleID = s.ScheduleID,
    DateCreated = s.DateCreated,
    Protected = s.Protected,
    StartTime = s.StartTime,
    FinishTime = s.FinishTime,
    Processed = s.Processed,
    CoreSnapshotDatabaseName = s.CoreSnapshotDatabaseName,
    Removed = s.Removed,
    SnapshotID = s.SnapshotID,
    EmailNotification = s.EmailNotification,
    Email = s.Email,
    ServerID = s.ServerID,
    DateRequested = s.DateRequested,
    Canceled = s.Canceled,
    Active = s.Active,
    LastSnapshotQueueActionID =
        s.SnapshotQueueActions.OrderByDescending(o => o.ActionDate)
            .ThenByDescending(o => o.SnapshotQueueActionID)
            .FirstOrDefault()
            .ActionID,
    LastAction =
        s.SnapshotQueueActions.OrderByDescending(o => o.ActionDate)
            .ThenByDescending(o => o.SnapshotQueueActionID)
            .FirstOrDefault()
            .SnapshotAction.Description,
    SnapshotLogCount = s.SnapshotGenerationLogs.Count(),
    SnapshotDefinition = s.SnapshotDefinition.Name,
    Server = s.Server.ServerName,
    ScheduleName = s.Schedule.Name,
    ClientName = s.SnapshotDefinition.Client.ClientName_Long
};
Sign up to request clarification or add additional context in comments.

3 Comments

It wont compile. I get the error "Method, delegate or event is expected. I also tried code return _db.SnapshotQueues .Include(c => c.SnapshotDefinition) .Include(c => c.SnapshotDefinition.Client) .Include(c => c.Server) .Select(s => _snapshotQueueModelGet.Compile().Invoke(s)) .Where(s => s.SnapshotDefinitionID == snapshotDefinitionID) .OrderBy(sortFieldExpression);
.Select(_snapshotQueueModelGet) is the way to use it.
I need to pass in another set of data to link to. How do I call this? private readonly Expression<Func<SnapshotDefinition, DbSet<Schedule>, SnapshotDefinitionModel>> _snapshotDefinitionModelGet = (s, t) => new SnapshotDefinitionModel { SnapshotDefinitionID = s.SnapshotDefinitionID, }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.