I want to sum of all Volume & TotalTimes Column after Group BY from DataTable Alias as Temp_DT. Remember Volume & All TotalTimes Column may have null or blank value.
Can anyone help me to get the code through Linq Method
Sample Temp_DT:
Result should be in this format
I have tried the below code, but Temp_DT result is Null.
var Temp_DT = tempdt.AsEnumerable().Select(x =>
new
{
UID = x.Field<string>("UID"),
EMPNAME = x.Field<string>("Emp Name"),
EMPROLE = x.Field<string>("Role"),
SUPID = x.Field<string>("Sup ID"),
SUPNAME = x.Field<string>("Sup Name"),
DESIGNATION = x.Field<string>("Designation"),
VOLUME = x.Field<int>("Volume"),
LOGINTIME = x.Field<TimeSpan>("Login Time"),
BREAKTIME = x.Field<TimeSpan>("Break Time"),
HANDLETIME = x.Field<TimeSpan>("Handle Time"),
ACTIVETIME = x.Field<TimeSpan>("Active Time"),
HOLDTIME = x.Field<TimeSpan>("Hold Time"),
ACWTIME = x.Field<TimeSpan>("ACW"),
IDLETIME = x.Field<TimeSpan>("Idle"),
PRODUCTIVE = x.Field<TimeSpan>("Productive"),
NONPRODUCTIVE = x.Field<TimeSpan>("Non Productive"),
USERERROR = x.Field<TimeSpan>("User Error Time")
}).GroupBy(s => new { s.UID, s.EMPNAME, s.EMPROLE, s.SUPID, s.SUPNAME, s.DESIGNATION })
.Select(g => new
{
g.Key.UID,
g.Key.EMPNAME,
g.Key.EMPROLE,
g.Key.SUPID,
g.Key.SUPNAME,
g.Key.DESIGNATION,
VOLUME = g.Sum(x => Convert.ToInt16(x.VOLUME)),
LOGINTIME = new TimeSpan(g.Sum(x => x.LOGINTIME.Ticks)),
BREAKTIME = new TimeSpan(g.Sum(x => x.BREAKTIME.Ticks)),
HANDLETIME = new TimeSpan(g.Sum(x => x.HANDLETIME.Ticks)),
ACTIVETIME = new TimeSpan(g.Sum(x => x.ACTIVETIME.Ticks)),
HOLDTIME = new TimeSpan(g.Sum(x => x.HOLDTIME.Ticks)),
ACWTIME = new TimeSpan(g.Sum(x => x.ACWTIME.Ticks)),
IDLETIME = new TimeSpan(g.Sum(x => x.IDLETIME.Ticks)),
PRODUCTIVE = new TimeSpan(g.Sum(x => x.PRODUCTIVE.Ticks)),
NONPRODUCTIVE = new TimeSpan(g.Sum(x => x.NONPRODUCTIVE.Ticks)),
USERERROR = new TimeSpan(g.Sum(x => x.USERERROR.Ticks)),
});
You have to Parse the TimeSpan and Sum by using Ticks, like below.
var Temp_DT = tempdt.AsEnumerable().Select(x =>
new
{
UID = x["UID"],
EMPNAME = x["Emp Name"],
EMPROLE = x["Role"],
SUPID = x["Sup ID"],
SUPNAME = x["Sup Name"],
DESIGNATION = x["Designation"],
VOLUME = x["Volume"],
ERRORTIME = x["Error_Time"],
ACWTIME = x["ACW"],
BREAKTIME = x["Break Time"],
IDLETIME = x["Idle"],
NONPRODUCTIVE = x["Non Productive"],
}).GroupBy(s => new { s.UID, s.EMPNAME, s.EMPROLE, s.SUPID, s.SUPNAME, s.DESIGNATION })
.Select(g => {
var grouped = g.ToList();
return new
{
UID = g.Key.UID,
EMPNAME = g.Key.EMPNAME,
EMPROLE = g.Key.EMPROLE,
SUPID = g.Key.SUPID,
SUPNAME = g.Key.SUPNAME,
DESIGNATION = g.Key.DESIGNATION,
VOLUME = grouped.Sum(x => Convert.ToInt16(x.VOLUME)),
Error_Time = new TimeSpan(grouped.Select(x => ConvertTimeSpan(x.ERRORTIME.ToString())).ToList().Sum(r=> r.Ticks)),
ACW = new TimeSpan(grouped.Select(x => ConvertTimeSpan(x.ACWTIME.ToString())).ToList().Sum(r=> r.Ticks)),
Break = new TimeSpan(grouped.Select(x => ConvertTimeSpan(x.BREAKTIME.ToString())).ToList().Sum(r=> r.Ticks)),
Idle = new TimeSpan(grouped.Select(x => ConvertTimeSpan(x.IDLETIME.ToString())).ToList().Sum(r=> r.Ticks)),
NonProductive = new TimeSpan(grouped.Select(x => ConvertTimeSpan(x.NONPRODUCTIVE.ToString())).ToList().Sum(r=> r.Ticks))
};
}).ToList();
The Conversion method is,
private static TimeSpan ConvertTimeSpan(string str)
{
TimeSpan outputValue;
TimeSpan.TryParse(str, out outputValue);
return outputValue;
}
C# Fiddle with sample data.
Related
I have a online dataset that I am looping through to save it to a sqlite database. It works well, however the 'count' in which it is sequentially looping through is based on the ID column, however there are instances where the IDs (for the category that I am filtering on) are not sequential. I'd rather loop through row number or similar if possible - but I can't seem to find a way to do it. Below is my code:
Note the count starts at 793 because this is the ID of the first 'surface' categorised record
private async void updateAssetRegisterLocal()
{
try
{
var current = Connectivity.NetworkAccess;
if (current != NetworkAccess.Internet)
{
await DisplayAlert("No Internet Connectivity", "Move to a location with mobile coverage and try again", "OK");
}
else
{
UserDialogs.Instance.ShowLoading();
HttpClient client = new HttpClient();
var response = await client.GetStringAsync("https://XXXX.azurewebsites.net/api/assets");
var onlineAssets = JsonConvert.DeserializeObject<List<AssetRegister>>(response);
var assetsPrelim = onlineAssets
.Where(w => w.Asset_Category == "Surface")
.OrderBy(d => d.ID)
.ToList();
;
using (SQLiteConnection conn = new SQLiteConnection(App.FilePath))
{
try
{
conn.DropTable<AssetRegister>();
}
catch
{
await DisplayAlert("Unsuccessful", "Can't Access", "OK");
}
}
for (int count = 793; count <= (assetsPrelim.Count + 793); count++)
{
var assets = assetsPrelim.Where(x => x.ID == count);
var id = assets.Select(l => l.ID).FirstOrDefault();
var asset_ID = assets.Select(l => l.Asset_ID).FirstOrDefault();
var road_ID = assets.Select(l => l.Road_ID).FirstOrDefault();
var segmentString = assets.Select(l => l.AssetSegmentString).FirstOrDefault();
var hierarchy = assets.Select(l => l.Road_Hierarchy).FirstOrDefault();
var assetCategory = assets.Select(l => l.Asset_Category).FirstOrDefault();
var lat = assets.Select(l => l.Lat).FirstOrDefault();
var inspectionDue = assets.Select(l => l.Inspection_Due).FirstOrDefault();
var lon = assets.Select(l => l.Lon).FirstOrDefault();
var stdRoadId = assets.Select(l => l.StdRoadID).FirstOrDefault();
var assetType = assets.Select(l => l.Asset_Type).FirstOrDefault();
var inspectionDate = assets.Select(l => l.Last_Inspection_Date).FirstOrDefault();
using (SQLiteConnection con = new SQLiteConnection(App.FilePath))
{
con.CreateTable<AssetRegister>();
var assetsLocal = con.Table<AssetRegister>().ToList();
int arlID = assetsLocal.Count + 1;
AssetRegister arl = new AssetRegister()
{
ID = id,
Asset_ID = asset_ID,
Asset_Type = assetType,
Asset_Category = assetCategory,
Road_ID = road_ID,
Road_Hierarchy = hierarchy,
AssetSegmentString = segmentString,
Inspection_Due = inspectionDue,
StdRoadID = stdRoadId,
Lat = lat,
Lon = lon,
Last_Inspection_Date = inspectionDate,
};
using (SQLiteConnection conn = new SQLiteConnection(App.FilePath))
{
conn.CreateTable<AssetRegister>();
int rowsAdded = conn.Insert(arl);
conn.Close();
}
}
}
await DisplayAlert("Success", "Asset Register Updated on Device", "OK");
UserDialogs.Instance.HideLoading();
}
}
catch
{
await DisplayAlert("Error", "Could not get data - Report to System Adminstrator", "OK");
UserDialogs.Instance.HideLoading();
}
}
It looks like you can loop simply iterating using foreach
Instead of
for (int count = 793; count <= (assetsPrelim.Count + 793); count++)
{
var assets = assetsPrelim.Where(x => x.ID == count);
var id = assets.Select(l => l.ID).FirstOrDefault();
var asset_ID = assets.Select(l => l.Asset_ID).FirstOrDefault();
var road_ID = assets.Select(l => l.Road_ID).FirstOrDefault();
var segmentString = assets.Select(l => l.AssetSegmentString).FirstOrDefault();
var hierarchy = assets.Select(l => l.Road_Hierarchy).FirstOrDefault();
var assetCategory = assets.Select(l => l.Asset_Category).FirstOrDefault();
var lat = assets.Select(l => l.Lat).FirstOrDefault();
var inspectionDue = assets.Select(l => l.Inspection_Due).FirstOrDefault();
var lon = assets.Select(l => l.Lon).FirstOrDefault();
var stdRoadId = assets.Select(l => l.StdRoadID).FirstOrDefault();
var assetType = assets.Select(l => l.Asset_Type).FirstOrDefault();
var inspectionDate = assets.Select(l => l.Last_Inspection_Date).FirstOrDefault();
...
you can have
foreach (var asset in assetsPrelim)
{
var id = asset.ID;
var asset_ID = asset.Asset_ID;
var road_ID = assets.Road_ID;
var segmentString = asset.AssetSegmentString;
var hierarchy = asset.Road_Hierarchy;
var assetCategory = asset.Asset_Category;
var lat = asset.Lat;
var inspectionDue = asset.Inspection_Due;
var lon = asset.Lon;
var stdRoadId = asset.StdRoadID;
var assetType = asset.Asset_Type;
var inspectionDate = asset.Last_Inspection_Date;
...
Simply use foreach() instead of for() loop,
for (var asset in assetsPrelim)
{
var id = asset.Id;
var asset_ID = asset.Asset_ID;
var road_ID = assets.Road_ID;
//...
}
Coming from SQL background I am used to joining 5-8 tables in single query.
I can not imagine doing the same with Linq lambda expression syntax.
Here I am joining 4-5 tables/collections.
EG:
var viewmodel = logs.Join(CargoElements.lstContainerLoadStatus.ToList(), l => l.LoadStatus, ls => ls.Value, (x, ls) =>
new
{
log = x,
LoadStatusDesc = ls.Text
})
.Join(db.CargoContainerSize, log => log.log.CargoContainerSizeID, ccsize => ccsize.Id, (log, ccsize) => new
{
log = log,
CargoContainerSizeIDDesc = ccsize.Size
}).Join(db.CargoContainerType, log => log.log.log.CargoContainerTypeID, cct => cct.Id, (log, cct) => new
{
log = log,
CargoContainerTypeIDDesc = cct.Name
}).GroupJoin(db.CargoFrom, log => log.log.log.log.CargoFromID, cf => cf.ID, (log, cf) => new
{
log = log,
cf = cf
}).SelectMany(temp => temp.cf.DefaultIfEmpty(), (temp, cf) => new
{
log = temp,
CargoFromIDDesc = cf.Description
}
)
.Select(x => new ContainerInLogsVM
{
ContainerInLogID = x.log.log.log.log.log.ContainerInLogID,
ContainerInID = x.log.log.log.log.log.ContainerInID,
CargoID = x.log.log.log.log.log.CargoID,
LoadStatus = x.log.log.log.log.log.LoadStatus,
LoadStatusDesc = x.log.log.log.log.LoadStatusDesc,
Shipper = x.log.log.log.log.log.Shipper,
CnFAgentName = x.log.log.log.log.log.CnFAgentName,
ShippingBill = x.log.log.log.log.log.ShippingBill,
ContainerNo = x.log.log.log.log.log.ContainerNo,
CargoContainerSizeID = x.log.log.log.log.log.CargoContainerSizeID,
CargoContainerSizeIDDesc = x.log.log.log.CargoContainerSizeIDDesc,
CargoContainerTypeID = x.log.log.log.log.log.CargoContainerTypeID,
CargoContainerTypeIDDesc = x.log.log.CargoContainerTypeIDDesc,
OtherType = x.log.log.log.log.log.OtherType,
VesselNo = x.log.log.log.log.log.VesselNo,
ShipperBillNo = x.log.log.log.log.log.ShipperBillNo,
SealOTLNo = x.log.log.log.log.log.SealOTLNo,
VoyageNo = x.log.log.log.log.log.VoyageNo,
BLNumber = x.log.log.log.log.log.BLNumber,
Purpose = x.log.log.log.log.log.Purpose,
CargoFromID = x.log.log.log.log.log.CargoFromID,
CargoFromIDDesc = x.CargoFromIDDesc,
OtherFrom = x.log.log.log.log.log.OtherFrom,
Status = x.log.log.log.log.log.Status,
Remark = x.log.log.log.log.log.Remark,
StatusChangedOn = x.log.log.log.log.log.StatusChangedOn,
StatusChangedBy = x.log.log.log.log.log.StatusChangedBy,
StatusChangedByDesc = "",
SysRemark = x.log.log.log.log.log.SysRemark
}
).ToList();
This is ridiculous! Or am I doing it wrong? There has to be a better way in LINQ.
I am looking for answers preferably in lambda expressions.
I have Three List<Results>
var list1 = new List<Results> {
new Results{ Empid = 1,Empname = "John",Rating = 1.33},
new Results{ Empid = 2,Empname = "Aarya",Rating = 1.6},
new Results{ Empid = 3,Empname = "Sansa",Rating = 1.6}
};
var list2 = new List<Results> {
new Results{ Empid = 1,Empname = "John",Rating = 2.33},
new Results{ Empid = 2,Empname = "Aarya",Rating = 2.6},
new Results{ Empid = 3,Empname = "Sansa",Rating = 1.6}
};
var list3 = new List<Results> {
new Results{ Empid = 1,Empname = "John",Rating = 0.33},
new Results{ Empid = 2,Empname = "Aarya",Rating = 0.6}
};
I want final result like(sum of all ratings based on Empid)
Final={Empid=1,Empname="John",Rating=3.99}
{Empid=2,Empname="Aarya",Rating=4.8}
{Empid=3,Empname="Sansa",Rating=3.2}
How to achieve this by using Linq, I am new to LinQ i am trying using GroupBy but I couldn't.
Use Concat to merge the lists and then a normal group by:
var result = list1.Concat(list2).Concat(list3)
.GroupBy(item => new { item.Empid, item.Empname }, item => item.Rating)
.Select(g => new {
Id = g.Key.Empid,
Name = g.Key.Empname,
Rating = g.Sum() });
Or in query syntax:
var result = from item in list1.Concat(list2).Concat(list3)
group item.Rating by new { item.Empid, item.Empname } into g
select new {
Id = g.Key.Empid,
Name = g.Key.Empname,
Rating = g.Sum()
};
sum of all ratings based on Empid - Note that if the id and name correlate then it is simplest to group by the two of them as in the example above. Otherwise, group by id and retrieve for each group the .First().Empname
first you should concat all lists together and then write something like this:
var q = from p in concatlist
group p by new { p.Empid, p.Empname} into g
select new
{
Empid = g.Key.Empid,
Empname = g.Key.Empname,
Rating = g.Sum(c=>c.Rating)
};
Or you can use Enumerable.SelectMany method to "flatten" lists and then use same grouping as in other answers
var final =
new[] { list1, list2, list3 }.SelectMany(list => list)
.GroupBy(result => new { result.EmpId, result.EmpName })
.Select(group => new Results
{
EmpId = group.Key.EmpId,
EmpName = group.Key.EmpName,
Rating = group.Sum(result => result.Rating)
});
With SelectMany you will be able to query dynamic amount of lists
I am creating Azure Mobile app.
In the api I created following list with Entity Framework 6.1.
The problem is that it is too big in the Select methods,
public IHttpActionResult GetAllQABundle(string qAUser_id, int offset = 0, int limit = 20)
{
List<QABundleWithCommentDto> qABundleWithCommentDtos = context.QABundles
.Where(b => b.TeamId == null)
.OrderByDescending(b => b.UpdatedAt)
.Skip(offset)
.Take(limit)
.Select(b => new QABundleWithCommentDto()
{
Id = b.Id,
TagForFreeFormat = b.TagForFreeFormat,
MovieUrl = b.Movie.MovieUrl,
MovieThumbnailUrl = b.Movie.MovieThumbnailUrl,
MovieStreamUrl = b.Movie.MovieStreamUrl,
NumberOfViews = b.Movie.NumberOfViews,
Title = b.Title,
Description = b.Description,
QuestionType = b.QuestionType,
WannaKnowId = b.WannaKnows.Where(w => w.QAUserId == qAUser_id).FirstOrDefault().Id,
WannaKnowCount = b.WannaKnows.Count,
QAUserThumbnailUrl = b.QAUser.ThumbnailUrl,
QAUserId = b.QAUser.Id,
UserName = b.QAUser.UserName,
UpdatedAt = b.UpdatedAt,
GenereDtos = b.Generes.Select(t => new GenereDto() { GenereId = t.Id, GenereName = t.Name }).ToList(),
CommentDtos = b.Comments.OrderByDescending(c => c.UpdatedAt).Take(20).Select(c => new CommentDto()
{
Id = c.Id,
Text = c.Text,
MovieUrl = c.Movie.MovieUrl,
MovieThumbnailUrl = c.Movie.MovieThumbnailUrl,
QAUserId = c.QAUserId,
UserName = c.QAUser.UserName,
QAUserBelongsTo = c.QAUser.BelongsTo,
QAUserThumbnailUrl = c.QAUser.ThumbnailUrl,
CommentCreatedAt = c.CreatedAt,
Likes = c.Likes.Count,
LikeId = c.Likes.Where(x => x.QAUserId == qAUser_id).FirstOrDefault().Id,
UpdatedAt = c.UpdatedAt,
QABundleId = c.QABundleId
}).ToList(),
TeamDto = new TeamDto()
{
Id = b.TeamId,
Name = b.Team.Name,
FollowedDtos = b.Team.QAUsers.Select(u => new FollowedDto()
{
Id = u.Id,
UserName = u.UserName,
ThumbnailUrl = u.ThumbnailUrl,
}).ToList()
},
BestAnswerDto = new BestAnswerDto() { Id = b.BestAnswerId, CommentId = b.BestAnswer.CommentId }
})
.ToList();
return Json(qABundleWithCommentDtos);
}
I would like to define following part as another function, but I do not know how I implement that.
Does anyone have good idea?
b => new QABundleWithCommentDto()
{
Id = b.Id,
TagForFreeFormat = b.TagForFreeFormat,
MovieUrl = b.Movie.MovieUrl,
MovieThumbnailUrl = b.Movie.MovieThumbnailUrl,
MovieStreamUrl = b.Movie.MovieStreamUrl,
NumberOfViews = b.Movie.NumberOfViews,
Title = b.Title,
Description = b.Description,
QuestionType = b.QuestionType,
WannaKnowId = b.WannaKnows.Where(w => w.QAUserId == qAUser_id).FirstOrDefault().Id,
WannaKnowCount = b.WannaKnows.Count,
QAUserThumbnailUrl = b.QAUser.ThumbnailUrl,
QAUserId = b.QAUser.Id,
UserName = b.QAUser.UserName,
UpdatedAt = b.UpdatedAt,
GenereDtos = b.Generes.Select(t => new GenereDto() { GenereId = t.Id, GenereName = t.Name }).ToList(),
CommentDtos = b.Comments.OrderByDescending(c => c.UpdatedAt).Take(20).Select(c => new CommentDto()
{
Id = c.Id,
Text = c.Text,
MovieUrl = c.Movie.MovieUrl,
MovieThumbnailUrl = c.Movie.MovieThumbnailUrl,
QAUserId = c.QAUserId,
UserName = c.QAUser.UserName,
QAUserBelongsTo = c.QAUser.BelongsTo,
QAUserThumbnailUrl = c.QAUser.ThumbnailUrl,
CommentCreatedAt = c.CreatedAt,
Likes = c.Likes.Count,
LikeId = c.Likes.Where(x => x.QAUserId == qAUser_id).FirstOrDefault().Id,
UpdatedAt = c.UpdatedAt,
QABundleId = c.QABundleId
}).ToList(),
TeamDto = new TeamDto()
{
Id = b.TeamId,
Name = b.Team.Name,
FollowedDtos = b.Team.QAUsers.Select(u => new FollowedDto()
{
Id = u.Id,
UserName = u.UserName,
ThumbnailUrl = u.ThumbnailUrl,
}).ToList()
},
BestAnswerDto = new BestAnswerDto() { Id = b.BestAnswerId, CommentId = b.BestAnswer.CommentId }
Its type is Expression<Func<QABudle, QABundleWithCommentDto>> so if you write:
Expression<Func<QABudle, QABundleWithCommentDto>> selector = b => new
{
//rest of the code
}
now you can use selector like this: .Select(selector)
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.
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
};