I want to modify the data in my object using Linq - c#

var todate = Filters.Where(it => it.Value == "ApplicationDateToSearch").Select(it =>
{
if (DateTime.TryParse(it.Description, out DateTime ConvertedToDate))
{
it.Description = ConvertedToDate.AddHours(23).AddMinutes(59).AddSeconds(59).ToString();
}
})?.FirstOrDefault();
Visual Studio doesn't seem to like this.
List<EmployeeRole> Filters
public class EmployeeRole
{
public String Description { get; set; }
public String Value { get; set; }
public int IntValue { get; set; }
}

The 'select' statement is used to select the properties you can't modify in that, so you have to use the 'ForEach' statement for that. But 'ForEach' statement doesn't have any return type so after that you can use FirstOrDefault
var x = Filters.Where(i => i.Value == "ApplicationDateToSearch").ToList();
x.ForEach(i => i.Description = DateTime.TryParse(i.Description, out DateTime ConvertedToDate) ? ConvertedToDate.AddHours(23).AddMinutes(59).AddSeconds(59).ToString() : string.Empty);
var todate = x.FirstOrDefault();

Related

Group By query in mvc5

Hi i want to write sql Group by query in C# of my MVC5 application.
In the above image I have group by query which i wrote in sql . That I want to write in C# front end.
I tried to write query in front end. But I am getting error which is mentioned in the image. Now I want to write that Group By query in C# and want to display the each employee with count (output same as mentioned in the first image). Can anyone help me to resolve this issue?
My ViewModel(Dashnboard View model)
public class DashboardViewmodel
{
public List<CustomerTypeCountModel> CustomerTypesCountModels { get; set; }
public List<View_VisitorsForm> Visits { get; set; }
public CustomerTypeViewModel CustomerTypeViewModels { get; set; }
public int sizingcount { get; set; }
public int Processingcount { get; set; }
//here i declared two properties
public string EmployeeName { get; set; }
public string EmployeeCount { get; set; }
}
My Controller code
[HttpGet]
public ActionResult SalesVisit()
{
return View();
}
public ActionResult GetDatesFromSalesVisit(DashboardViewmodel dvm)
{
var fromdate = Convert.ToDateTime(dvm.CustomerTypeViewModels.FromDate);
var todate = Convert.ToDateTime(dvm.CustomerTypeViewModels.ToDate);
List<View_VisitorsForm> empcount = new List<View_VisitorsForm>();
if (DepartmentID == new Guid("47D2C992-1CB6-44AA-91CA-6AA3C338447E") &&
(UserTypeID == new Guid("106D02CC-7DC2-42BF-AC6F-D683ADDC1824") ||
(UserTypeID == new Guid("B3728982-0016-4562-BF73-E9B8B99BD501"))))
{
var empcountresult = db.View_VisitorsForm.GroupBy(G => G.Employee)
.Select(e => new
{
employee = e.Key,
count = e.Count()
}).ToList();
empcount = empcountresult ;//this line i am getting error
}
DashboardViewmodel obj = new DashboardViewmodel();
return View("SalesVisit", obj);
}
When you use a GroupBy you get an IEnumerable<IGrouping<Key,YourOriginalType>> so you do not have .Employee and .VisitingID properties.
Change as following:
public class EmployeeCount
{
public string Employee {get; set;}
public int Count {get; set;}
}
List<EmployeeCount> result = db.View_VisitorsForm
.Where(item => item.VisitingDate >= beginDate && item.VisitingDate < endDate)
.GroupBy(G => G.Employee)
.Select(e =>new EmployeeCount
{
employee = e.Key,
count = e.Count()
}).ToList();
//Now add the result to the object you are passing to the View
Also keep in mind that you are not instantiating objects of type View_VisitorsForm but an anonymous object so assigning the result to empcount yet alone with the added FirstOrDefault will not compile
To pass this structure to the View and present it check this question
hope this helps you
var query = db.View_VisitorsForm.Where(o => o.VisitingDate >= new DateTime(2016,10,01) && o.VisitingDate <= new DateTime(2016, 10, 30)).GroupBy(G => G.Employee)
foreach (var item in query)
{
Console.WriteLine($"Employee Id {item.Key} : Count :{item.Count()}");
}

How to convert Null to String with Linq to Entity

I'm trying to use reflection within a linq query to change a Decimal Null value to a string value. My code produce this error;
"Object of type System.String cannot be converted to type System.Nullable System.Decimal"
Thanks for your help.
public class ReportData
{
public IEnumerable<SASF> GetLongReportData(string commSubGp)
{
var context = new Entities();
string myDate = "2014-03-18";
DateTime date = Convert.ToDateTime(myDate);
var result = new List<SASF>();
if (commSubGp == "F00")
{
result = (from a in context.SASF
where a.RDate == date &&
a.COMM_SGP.CompareTo("F00") <= 0
orderby a.Conmkt, a.MKTTITL descending
select a).ToList();
//Here I'm trying to use reflection to loop through the object and set any value that's null to string value
result.ForEach(reflect =>
{
reflect.GetType().GetProperties().ToList().ForEach(p =>
{
var checkValue = p.GetValue(reflect, null);
if (checkValue == null)
{
p.SetValue(reflect, "non-reportable", null);
}
});
});
return result.ToList();
}
return results;
}
}
Since your property type is Decimal? the string "non-reportable" can not be converted to Decimal and the value fails to set. You could set it to zero however:
p.SetValue(reflect, Decimal.Zero, null)
Or any decimal value for that matter.
p.SetValue(reflect, Decimal.MinValue, null)
p.SetValue(reflect, Decimal.MaxValue, null)
Not knowing what the data is to be used for in the end I have no idea whether this would be appropriate or not.
Using reflection to do this probably isn't the best solution as it is quite an expensive process. Utilising the method below allows you to be specific and output the data in a way you see fit (although you could do this on the DB side too).
Without knowing the structure of the SASF class I have just created a pseudo class.
This of course requires you to specifically map each field to your stringified class. You might be able to use some tool like AutoMapper (https://github.com/AutoMapper/AutoMapper) to do this for you.
public class ReportData
{
public IEnumerable<SASFStringified> GetLongReportData(string commSubGp)
{
var context = new Entities();
string myDate = "2014-03-18";
DateTime date = Convert.ToDateTime(myDate);
var result = new List<SASF>();
if (commSubGp == "F00")
{
result = (from a in context.SASF
where a.RDate == date &&
a.COMM_SGP.CompareTo("F00") <= 0
orderby a.Conmkt, a.MKTTITL descending
select a).ToList();
var stringifiedResult = new List<SASFStringified>();
foreach (var sasf in result)
{
stringifiedResult.Add(new SASFStringified
{
ID = sasf.ID,
Field1 = sasf.Field1.HasValue ? sasf.Field1.Value.ToString() : "non-reportable",
Field2 = sasf.Field2.HasValue ? sasf.Field2.Value.ToString() : "non-reportable",
DateField = sasf.DateField.ToShortDateString()
});
}
return stringifiedResult;
}
return results;
}
}
public class SASF
{
public int ID { get; set; }
public decimal? Field1 { get; set; }
public decimal? Field2 { get; set; }
public DateTime DateField { get; set; }
}
public class SASFStringified
{
public int ID { get; set; }
public string Field1 { get; set; }
public string Field2 { get; set; }
public string DateField { get; set; }
}

Orderby a string column in linq causes an error

I have a query like this :
List<PresentClass.userpresentation> q =
(dbconnect.tblUsers.Where(
i => i.permission == permission)
.Select(arg => new PresentClass.userpresentation {
email = arg.email, pass = arg.password,
name = arg.name+" "+arg.family })).ToList();
After adding an orderby :
List<PresentClass.userpresentation> q =
(dbconnect.tblUsers.Where(
i => i.permission == permission)
.Select(arg => new PresentClass.userpresentation {
email = arg.email, pass = arg.password,
name = arg.name+" "+arg.family })).OrderBy(i=>i.family).ToList();
I got this error :
The member
'Novitiate.AdminPortal.PresentationClass.PresentClass+userpresentation.family'
has no supported translation to SQL.
My class:
public class userpresentation
{
public string username { set; get; }
public string email { set; get; }
public string family { set; get; }
public string name { set; get; }
public string pass{ set; get; }
}
Why?
It looks like it's trying to translate the OrderBy() into a SQL statement on your projection.
Try adding the OrderBy() before Select() if you want the database to do the ordering, or after the ToList() if you want to do the ordering once the collection has been loaded.
var q = (dbconnect.tblUsers.Where(i => i.permission == permission)
.OrderBy(i=>i.family)
.Select(arg => new PresentClass.userpresentation {
email = arg.email,
pass = arg.password,
name = arg.name+" "+arg.family
})).ToList();

EF Subquery No Navigation Property

Im trying to compute a boolean field based on a subquery
var dtfs = cntx.Set<Models.DocTypeField>()
.Include(dtf => dtf.Field)
.Where(dtf => dtf.DocTypeId == docTypeId)
.Select(dtf => new
{
DocTypeField = dtf,
HasData = (cntx.Set<Models.DocumentData>()
.Any(dd => dd.DocTypeId == dtf.DocTypeId
&& dd.DataValues.Any(ddv => ddv.FieldId == dtf.FieldId)))
});
There is no navigation property(or traversable path) between DocTypeField and DocumentData. When I run the query above I get the following exception:
Test method
Core.Sebring.DataAccess.Ef.Test.EF_DocTypeDALTest.EF_DocTypeDALTest_GetDocTypeIndexes
threw exception:
System.NotSupportedException:
LINQ to Entities does not recognize the method
'System.Data.Entity.DbSet`1[Core.Sebring.Models.DocumentData]
Set[DocumentData]()' method, and this method cannot be translated
into a store expression.
Is there a linq to entity way of accomplishing the above query? I would rather not add a navigation property(or traversable path) between DocTypeField and DocumentData, if possible.
*UPDATE 1*
As a work around I did
class FieldDocTypeField
{
public int DocTypeFieldId { get; set; }
public int DocTypeId { get; set; }
public int FieldDataType { get; set; }
public int FieldId { get; set; }
public byte[] LastChanged { get; set; }
public bool Required { get; set; }
public string FieldName { get; set; }
public bool HasData { get; set; }
}
var dtfs = cntx.DbContext.Database.SqlQuery<FieldDocTypeField>(#"select dtf.*,f.*,
HasData = (CASE WHEN EXISTS(Select DocumentDataValue.FieldId
from DocumentData
inner join DocumentDataValue on DocumentData.DocumentDataId=DocumentDataValue.DocumentDataId
where DocumentData.DocTypeId = #DocTypeId AND dtf.FieldId = 1) THEN cast(1 as bit) ELSE cast(0 as bit) END)
from DocTypeField dtf
inner join Field f on dtf.FieldId = f.FieldId WHERE dtf.DocTypeId=#DocTypeId", new System.Data.SqlClient.SqlParameter("#DocTypeId", docTypeId));
foreach (var dtf in dtfs)
{
docTypeFields.Add(new Models.DocTypeField
{
DocTypeFieldId = dtf.DocTypeFieldId,
DocTypeId = dtf.DocTypeId,
FieldDataType = dtf.FieldDataType,
FieldId = dtf.FieldId,
LastChanged = dtf.LastChanged,
Required = dtf.Required,
FieldName = dtf.FieldName,
HasData = dtf.HasData
});
}
Its not so nice but it works and accomplishes the same things. I could not find a way to do the above using linq to entities without adding a nav property between DocTypeField and DocumentData entities.
You can pull the data in memory first and then do the 2nd select.
var dtfs = cntx.Set<Models.DocTypeField>()
.Include(dtf => dtf.Field)
.Where(dtf => dtf.DocTypeId == docTypeId)
.ToList() // pull the data to memory and then the following select can execute successfully.
.Select(dtf => new
{
DocTypeField = dtf,
HasData = (cntx.Set<Models.DocumentData>()
.Any(dd => dd.DocTypeId == dtf.DocTypeId
&& dd.DataValues.Any(ddv => ddv.FieldId == dtf.FieldId)))
});

How to extract result of Linq Expression?

My result Expression is
var result = dtFields.AsEnumerable().Join(dtCDGroup.AsEnumerable(),
fieldList=>fieldList.Field<string>("CDGroupID"),
cd=>cd.Field<string>("CDGroupID"),
(fieldList,cd) => new
{
FieldID = fieldList.Field<string>("FieldID"),
Name = cd.Field<string>("Name"),
CDCaption = fieldList.Field<string>("CDCaption"),
Priority = ((cd.Field<string>("Priority") == null) ? 99 : cd.Field<int>("Priority")),
fldIndex = fieldList.Field<string>("fldIndex")
}).OrderBy(result => result.Priority).ThenBy(result => result.fldIndex);
Casting above result to array or list throws an invalid cast exception.
How can extract result of above expression?
Add .ToArray() or .ToList() call respectively
Try to add a strongly typed type:
public class NewModule
{
public int FieldID { get; set; }
public string Name { get; set; }
public string CDCaption { get; set; }
public int Priority { get; set; }
public int fldIndex { get; set; }
}
instead of the anonymous type then you could use ToList<NewModule>() like this:
var result = dtFields.AsEnumerable().Join(dtCDGroup.AsEnumerable(),
fieldList=>fieldList.Field<string>("CDGroupID"),
cd=>cd.Field<string>("CDGroupID"),
(fieldList,cd) => new NewModule
{
FieldID = fieldList.Field<string>("FieldID"),
Name = cd.Field<string>("Name"),
CDCaption = fieldList.Field<string>("CDCaption"),
Priority = ((cd.Field<string>("Priority") == null) ? 99 : cd.Field<int>("Priority")),
fldIndex = fieldList.Field<string>("fldIndex")
}).OrderBy(result => result.Priority)
.ThenBy(result => result.fldIndex)
.ToList<NewModule>();

Categories

Resources