I have module which is not mapped to database( sql server) and is only use to generate report.
public class Report
{
public int USERID { get; set; }
public DateTime DateToCal { get; set; }
public string Name { get; set; }
public string Position { get; set; }
public TimeSpan? Intime { get; set; }
public TimeSpan? OutTime { get; set; }
}
I generate a query and fill some properties(USERID, DateToCal, Name, Position, Intime) of Report and some properties of Report remains null ( as OutTime is null)
var query = .....;
Now what I want iterate on items of query( of type Report) and set value for null properties OutTime as
foreach(var items in query)
{
var outtime= from x in con.CHECKINOUTs
where x.USERID == items.USERID && EntityFunctions.TruncateTime(x.CHECKTIME) == EntityFunctions.TruncateTime(items.DateToCal && x.CHECKTYPE == "O"
select x.CHECKTIME
.Single();
items.OutTime= outtime.TimeOfDay;
}
Now problem is, on mousehover to items.OutTime with in foreach there appear value but if I out from foreach and mousehover to query there is still OutTime is null. There not appear value what I set. Is this is possible to set value of entities such way. Or what is my problem?
Thank you.
Save query results locally before iterating over them:
var query = ....ToList();
Looks like in your case query executed two times - first time when you are updating OutTime property, and second time when you are iterating over query items (either looking in debugger or displaying in UI). So, when query executed second time, you see completely new set of objects as query result (which have original null values of OutTime).
BTW Consider to use single JOIN query instead of making separate outtime query for each item in your main query.
Try code something like this:
public class Report
{
public int USERID { get; set; }
public DateTime DateToCal { get; set; }
public string Name { get; set; }
public string Position { get; set; }
private TimeSpan? _intime;
public TimeSpan Intime {
get { return _intime ?? new TimeSpan(0); }
set { _intime = value; }
}
private TimeSpan? _outTime;
public TimeSpan OutTime
{
get { return _outTime ?? new TimeSpan(0); }
set { _outTime = value; }
}
}
Related
I have a List<MyObject>.
public class MyObject
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateTime { get; set; }
public decimal Value { get; set; }
public decimal ValueToCalculate { get; set; }
}
The ValueToCalculate is not set yet.
How can I set the ValueToCalculate by the Value of the minimum DateTime grouped by FirstName and LastName.
I've tried various versions with GroupBy/MaxBy/SelectMany and whatever without success.
First do the grouping, then find the object with the minimum date in each group to get the value from and finally update the objects in this group with this value
var groups = list
.GroupBy(o => (o.FirstName, o.LastName));
foreach (var group in groups) {
decimal value = group
.OrderBy(o => o.DateTime)
.First().Value;
foreach (MyObject item in group) {
item.ValueToCalculate = value;
}
}
I build a tuple with the first and last names as group key to make grouping by the two properties possible.
Each group is an enumerable of MyObject we can enumerate to get the objects belonging to this group. To get the object with the minimum DateTime I order the objects by this DateTime and get the first one from which I extract the Value.
It is often easier to do the things step by step instead of trying to merge everything into a single unreadable LINQ query just to save 2 lines of code.
So I want to display an output that is group by two fields: SubsidiaryCode and AssetCreatedDate. My problem is it displays the grouping values redundantly.
I suspect it duplicates because of my Detail class.
What I want is:
But it displays like this:
LINQ query:
public DateTime FromDate { get; set; }
public DateTime ToDate { get; set; }
public IList<AssetListTemplate> List = new List<AssetListTemplate>();
public IList<AssetListTemplate> GetList()
{
using (var ctx = LinqExtensions.GetDataContext<NXpert.FixedAsset.DataAccess.FixedAssetDataContext>("AccountingDB"))
{
var list = (from x in ctx.DataContext.AssetRegistryEntities
where x.SubsidiaryCode2 != "" && x.SubsidiaryCode2.ToUpper().Contains("y-") && x.AssetCreatedDate>=FromDate && x.AssetCreatedDate <= ToDate
group new { x.SubsidiaryCode2, x.AssetCreatedDate,x.AssetCategoryID } by x into groupedList
select new AssetListTemplate
{
IsSelected = false,
SubsidiaryCode = groupedList.Key.SubsidiaryCode2,
AssetCreatedDate = groupedList.Key.AssetCreatedDate,
AssetCategory = groupedList.Key.AssetCategoryID
}
).OrderBy(x => x.SubsidiaryCode).ThenBy(y => y.AssetCreatedDate).ToList();
List = list;
foreach (var item in List)
{
var details = (from x in ctx.DataContext.AssetRegistryEntities
join y in ctx.DataContext.AssetCategoryEntities on x.AssetCategoryID equals y.AssetCategoryID
join z in ctx.DataContext.FixedAssetOtherInfoEntities on x.AssetCode equals z.AssetCode
where x.SubsidiaryCode2 == item.SubsidiaryCode
select new Details
{
AssetCode = x.AssetCode,
AssetCodeDesc = y.AssetCategoryDesc,
AssetDesc = x.AssetCodeDesc,
DepInCharge = z.DepartmentInCharge,
SerialNo = x.SerialNumber,
ModelNo = x.ModelNumber
}).ToList();
item.Details = details;
}
return List;
}
}
}
public class AssetListTemplate
{
public bool IsSelected { get; set; }
public string SubsidiaryCode { get; set; }
public DateTime? AssetCreatedDate { get; set; }
public string AssetCategory { get; set; }
public List<Details> Details { get; set; }
}
public class Details {
public string AssetCode { get; set; }
public string AssetCodeDesc { get; set; }
public string AssetDesc { get; set; }
public string DepInCharge { get; set; }
public string SerialNo { get; set; }
public string ModelNo { get; set; }
}
SQL Query:
SELECT Are_SubsidiaryCode2[SubsidiaryCode],Are_AssetCreatedDate[AssetCreatedDate],Are_AssetCategoryID[AssetCategory]
FROM E_AssetRegistry
WHERE Are_SubsidiaryCode2<>''
AND Are_SubsidiaryCode2 LIKE '%Y-%'
GROUP BY Are_SubsidiaryCode2
,Are_AssetCreatedDate
,Are_AssetCategoryID
ORDER BY AssetCreatedDate ASC
You don't seem to be using the grouping for any aggregate function , so you could make life simpler by just using distinct:
from x in ctx.DataContext.AssetRegistryEntities
where x.SubsidiaryCode2.Contains("y-") && x.AssetCreatedDate>=FromDate && x.AssetCreatedDate <= ToDate
select new AssetListTemplate
{
IsSelected = false,
SubsidiaryCode = groupedList.Key.SubsidiaryCode2,
AssetCreatedDate = groupedList.Key.AssetCreatedDate.Value.Date,
AssetCategory = groupedList.Key.AssetCategoryID
}
).Distinct().OrderBy(x => x.SubsidiaryCode).ThenBy(y => y.AssetCreatedDate).ToList();
Side note, you don't need to assign a list to a clas variable and also return it; I'd recommend just to return it. If you're looking to cache the results, make the class level var private, assign it and return it first time and just return it the second time (use the null-ness of the class level var to determine if the query has been run)
Expanding on the comment:
You don't need to store your data in a public property and also return it. Don't do this:
public class Whatever{
public string Name {get;set;}
public string GetName(){
var name = "John";
Name = name;
return name;
}
Typically we would either return it:
public class Whatever{
public string GetName(){
var name = MySlowDatabaseCallToCalculateAName();
return name;
}
//use it like:
var w = new Whatever();
var name = w.GetName();
Or we would store it:
public class Whatever{
public string Name {get;set;}
public void PopulateName(){
Name = MySlowDatabaseCallToCalculateAName();
}
//use it like
var w = new Whatever();
w.PopulateName();
var name = w.Name;
We might have something like a mix of the two if we were providing some sort of cache, like if the query is really slow and the data doesn't change often, but it is used a lot:
public class Whatever{
private string _name;
private DateTime _nameGeneratedAt = DateTime.MinValue;
public string GetName(){
//if it was more than a day since we generated the name, generate a new one
if(_nameGeneratedAt < DateTime.UtcNow.AddDays(-1)){
_name = MySlowDatabaseCallToCalculateAName();
_nameGeneratedAt = DateTime.UtcNow; //and don't do it again for at least a day
}
return _name;
}
This would mean that we only have to do the slow thing once a day, but generally in a method like "Get me a name/asset list/whatever" we wouldn't set a public property as well as return the thing; it's confusing for callers which one to use - they want the name; should they access the Name property or call GetName? If the property was called "MostRecentlyGeneratedName" and the method called "GenerateLatestName" it would make more sense - the caller can know they might call Generate..( first, and then they could use MostRecently.. - it's like a caching; the calling class can decide whether to get the latest, or reuse a recently generated one (but it does introduce the small headache of what happens if some other operation does a generate in the middle of the first operation using the property..)..
..but we probably wouldn't do this; instead we'd just provide the Generate..( method and if the caller wants to cache it and reuse the result, it can
I'm retrieving a list from a SQL database with following code :
var matInList = db.MaterialInLists
.Where(m => m.PartName == "ABC" &&
m.Month == "July").ToList();
and I'm trying to get parameters of list with foreach loop like
foreach (var quanIn in matInList)
{
string quant = quanIn.Quantity;
string Date = quanIn.Date;
totalIn = totalIn + Int32.Parse(quanIn.Quantity);
}
Problem is in foreach loop only 3rd line gets the correct data i.e. totalIn.
"quanIn.Quantity" & "quanIn.Date" show correct value in debug mode but it is not able to assign its value to left hand side variable.
MaterialInList class is this:
public partial class MaterialInList
{
public int ID { get; set; }
public string PartName { get; set; }
public string Quantity { get; set; }
public string Date { get; set; }
}
I have two model classes
public class GetProductNameRequest
{
public DateTime ExpiryDate { get; set; }
public bool IsActive { get; set; }
}
public class GetProductNameResponse
{
public List<string> ProductName { get; set; }
}
linq query:
public async Task<List<ProductSKU>> GetProductNames(GetProductNameRequest request)
{
var res = DbSet.Include(t => t.Product).Where(t => t.EndDate >= request.ExpiryDate && t.IsActive == request.IsActive).GroupBy(x => x.Product);
Contracts.Models.ProductNameResponse product = new Contracts.Models.ProductNameResponse();
foreach (var item in res)
{
product.ProductName = item.Key.ProductName;
}
}
So i'm unble get list of Product Names based on Id's plz let me know the solution.
productsku table:
SkuId ProductId Sku MRP CreatedOn UpdatedOn StartDate EndDate IsActive RowVersion
You have a number of problems in your code. Two most obvious reasons why you don't get anything in your product variable is that it is initialized inside the loop, and nothing gets added to it. The code should be something like
Contracts.Models.ProductNameResponse product = new Contracts.Models.ProductNameResponse();
foreach (var item in res)
{
product.ProductName.Add(item.Key.ProductName);
}
I also think your LINQ statement will still throw an error about one cursor not close while another one is open. Search for IQueryable vs IEnumerable issue. But you don't list that as a problem; so maybe in your data source it is fine.
How can I change this method so it also returns Max(t.StartTime) and Min(t.StartTime) with only using it in one line as below?
public IQueryable<Timetable> GetTimetables()
{
return from t in _entities.Timetables
select t;
}
/M
Off the top of my head (read: untested) and presuming StartTime is non-nullable:
public class TimetableWithMaxMin
{
public Timetable Timetable { get; set; }
public DateTime Max { get; set; }
public DateTime Min { get; set; }
}
public IQueryable<TimetableWithMaxMin> GetTimetables()
{
return from t in _entities.Timetables
select new TimetableWithMaxMin
{
Timetable = t,
Max = _entities.Timetables.Max(t => t.StartTime),
Min = _entities.Timetables.Min(t => t.StartTime)
};
}
This gets considerably more complicated when StartTime is nullable.
I don't know if this is applicable to Entity framework but with linq it's something like this
public IQueryable<Timetable> GetTimetables()
{
return from t in _entities.Timetables
select new {maxt = Max(t.StartTime), mint = Min(t.StartTime)};
}