I need to write a generic search method which i could use multiple times. My method is:
public List<GoldMakers> listofRecoverd_Reuse(int? EmployeeID, DateTime? Startdate, DateTime? EndDate)
{
List<GoldMakers> RecoveredGold = db.GoldMakers.Include(e => e.tbl_Employees)
.Where(x => (x.R_Employee_ID == EmployeeID || EmployeeID == null)
&& (x.R_Date >= Startdate || Startdate == null) && (x.R_Date <= EndDate || EndDate == null)).ToList();
return RecoveredGold;
}
I know it could be achieved using Generics, but i don't know how to work with linq using Generics.
public List<T> search<T>(T modelClass, int? EmployeeID, DateTime? Startdate, DateTime? EndDate)
{
list<T> result = db.Table<T>().where ........
return result;
}
Thank you.
Can you try like below:
public List<T> search<T>(DbSet<T> modelClass, int? EmployeeID, DateTime? Startdate, DateTime? EndDate) where T : class, new()
{
list<T> result = modelClass.where ........
return result;
}
You can call it like below
var tbl1 = search(db.table1, param1, param2, param3);
var tbl2 = search(db.table2, param1, param2, param3);
Related
model :
public class ReferenceParameterHistory
{
[Key]
public int IDReferenceParameterHistory { get; set; }
public double Value { get; set; }
public string Value_S { get; set; }
public DateTimeOffset CreatedAt { get; set; }
[Required]
public bool IsStable { get; set; }
public int? IDReference { get; set; }
public Reference Reference { get; set; }
[Required]
public int IDParameterTemplate { get; set; }
public ParameterTemplate ParameterTemplate { get; set; }
}
My code in ASP.NET core controller :
[HttpGet]
public async Task<IActionResult> GetReferenceParameterHistory(int? IDparameterTemplate,
int? IDreference,
DateTimeOffset? startDate,
DateTimeOffset? endDate,
bool latestOnly)
{
try
{
IQueryable<ReferenceParameterHistory> query = _context.ReferenceParameterHistory.OrderByDescending(rph => rph.IDReferenceParameterHistory);
if (IDparameterTemplate != null && IDparameterTemplate > 0)
query = query.Where(rph => rph.IDParameterTemplate == IDparameterTemplate);
if (IDreference != null && IDreference > 0)
query = query.Where(rph => rph.IDReference == IDreference);
if (startDate != null)
query = query.Where(rph=> rph.CreatedAt >= startDate);
if (endDate != null)
query = query.Where(rph => rph.CreatedAt <= endDate);
if (latestOnly)
{
// I tried this but it doesnt compile and I don't have idea how to solve this ....
//query = (from rph in query
// group rph by rph.IDParameterTemplate
// into groups
// where groups.Max(rph => rph.CreatedAt)
// select groups.Key);
}
var referenceParameterHistory = await query.AsNoTracking().ToListAsync();
if (referenceParameterHistory.Any())
return new ObjectResult(referenceParameterHistory);
return new NotFoundResult();
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return new StatusCodeResult(500);
}
}
I have a database table based on that ReferenceParameterHistory model class. I want to group records exctracted from that table by IDParameterTemplate and from each group I need to extract records that have the highest value in CreatedAt column (latest records). So each group contains many recods but I need to get only these with max value in CreatedAt column. The result should be IEnumerable of ReferenceParameterHistory since I store that query in an IQueryable variable and then send it to SQL Server to process the query. Commented code in my example is just what I tried but I don't know how to do that.
How can I solve that problem ?
You reused the variable rph inside the lambda.
How to select only the records with the highest date in LINQ
query = (from rph in query
group rph by rph.IDParameterTemplate into g
select g.OrderByDescending(t=>t.CreatedAt).FirstOrDefault());
I want to concatenate DateTime field and string field in MVC application.
I want Linq to Entities query to solve this. Here is my SQL query which I want in Linq.
Select accountid,TourID, ' ('+ convert(nvarchar(20), fromdate ,105) +')' + purpose as TourDetails
from Tour
where AccountID=#AccID;
As shown in above query I want to concat fromdate and purpose. I want to pass result of this query as JSON result.
Something like this:
public class Tour
{
public int accountid { get; set; }
public int TourID { get; set; }
public DateTime date { get; set; }
public string purpose { get; set; }
}
var t = new List<Tour>
{
new Tour
{
accountid = 1,
TourID = 2,
date = DateTime.Now,
purpose = "Testing"
}
};
var output = t.Where(c => c.accountid == accId).Select(k => new
{
accountid = k.accountid,
TourID = k.TourID,
TourDetails = k.date.ToString() + k.purpose
}).ToList();
var o = JsonConvert.SerializeObject(output);
You can use something like this if you're in a MVC Controller requiring an ActionResult as output :
//here 'context' is your DbContext implementation and Tours is your DbSet.
var TourDetails= context.Tours.Where(t=>t.AccountID==_AccID)
.Select(s=>new {
AccountID = s.accountid,
TourID = s.TourID,
//s.fromdate.ToString("yyyyMMddHHmmss") use this to format your date if needed
TourDetails = s.fromdate.ToString() + s.purpose
})
.ToList();
//JsonRequestBehavior.AllowGet only if your not using POST method
return Json(TourDetails, JsonRequestBehavior.AllowGet);
[HttpPost]
public ActionResult crbtmis(string submitbuttonoperator, DateTime fromdate, DateTime todate, string operatorname)
{
DateTime dfd = fromdate;
DateTime dtd = todate;
string soprtr = operatorname;
if (Session["user"] != null && Session["user"].ToString() == "MISADMIN")
{
switch (submitbuttonoperator)
{
case "Export":
return (ExportOprtrlist( fromdate, todate, operatorname));
case "Search":
return (SearchByOperator());
default:
return (View("LogOn"));
}
}
else
{
return RedirectToAction("LogOn");
}
}
I have defined three variable named as dfd,dtd and soprtr and want to use these variable into another ActionResult. Now please help me how will I do it?
In your action, you can use other action that contains some parameters:
public ActionResult crbtmis(string submitbuttonoperator, DateTime fromdate, DateTime todate, string operatorname)
{
//..your code
return RedirectToAction("OtherAction", new { dfd = dfd, dtd = dtd, soprtr = soprtr });
}
This is my class
public class Employee
{
public virtual List<Salary> Salaries { get; set; }
public bool CanAddSalary(Salary salary)
{
var count = (from x in Salaries where x.Month == salary.Month
&& x.Year == salary.Year select x).Count();
return count == 0;
}
public void AddSalary(Salary salary)
{
if(CanAddSalary(salary))
{
Salaries.Add(salary);
}
}
}
Entity Framework loads Employee with Salaries properties.
CanAddSalary method just check to avoid duplicates (Nothing modified the Salaries Collection right?).
If CanAddSalary return true then I call AddSalary method.
I call Entity Framework Context.SaveChanges() and throw me and exception.
You should use == instead of = in your return statement, because otherwise you'll always get false from CanAddSalary method:
public bool CanAddSalary(Salary salary)
{
var count = (from x in Salaries where x.Month == salary.Month
&& x.Year == salary.Year select x).Count();
return count == 0;
}
Your Salaries should really be
ICollection<Salary>
and doing an Any() will be faster than doing a Count()
Your
return count = 0;
is wrong which means
Salaries.Add(salary);
is adding a salary that is already in the Salaries collection, that's probably the exception
Try this, if you're still getting the exception, then post that on here too so we can see the error
cheers
Stu
public class Employee
{
public virtual ICollection<Salary> Salaries { get; set; }
public bool CanAddSalary(Salary salary)
{
return !(from x in Salaries where x.Month == salary.Month
&& x.Year == salary.Year select x).Any();
}
public void AddSalary(Salary salary)
{
if(CanAddSalary(salary))
{
Salaries.Add(salary);
}
}
}
Hi all i have method where i pass some parameters to the stored procedure and when i execute it i get this error
[The specified cast from a materialized 'System.Int32' type to the 'System.String' type is not valid.]
this is how i am calling my storedprocedure
public JsonResult CreatedBugs()
{
int year;
int month;
int projectid;
year = 2012;
month = 8;
projectid = 16;
var loggedbugs = db.ExecuteStoreQuery<LoggedBugs>("LoggedBugs #Year,#Month,#ProjectID", new SqlParameter("#Year",year ), new SqlParameter("#Month", month ), new SqlParameter("#ProjectID", projectid )).ToList();
var ClosedBugs = db.ExecuteStoreQuery<LoggedBugs>("ClosedBugs #Year,#Month,#ProjectID", new SqlParameter("#Year", year), new SqlParameter("#Month", month), new SqlParameter("#ProjectID", projectid)).ToList();
var model = new LoggedBugs
{
LoggedBugsCount = loggedbugs,
ClosedBugs = ClosedBugs
};
return Json(model, JsonRequestBehavior.AllowGet);
}
and this is my StoredProcedure
alter procedure LoggedBugs
(
#Year int,
#Month int,
#ProjectID int
)
as
begin
SELECT projectName,
ProjectYear,
ProjectMonth,
Week1, Week2, Week3, Week4, Week5
FROM (
Select p.projectName,YEAR(b.CreatedDate) ProjectYear, MONTH(b.CreatedDate) ProjectMonth,
'Week' + CAST(DATEDIFF(week, DATEADD(MONTH, DATEDIFF(MONTH, 0, b.CreatedDate), 0), b.CreatedDate)+1 AS VARCHAR) as [Weeks],
b.BUGID
From BUGS b inner join projects p on b.ProjectId = p.ProjectId
Where DatePart(year, CreatedDate) = #Year and datepart(month, Createddate) = #Month and b.projectid = #ProjectID
) p
PIVOT (COUNT(BUGID) FOR [Weeks] IN (WEEK1, WEEK2, WEEK3, Week4, Week5)) AS pvt
end
where am i doing wrong here
Edit1
here is my LoggedBug Class
public class LoggedBugs
{
public string projectName { get; set; }
public string ProjectYear { get; set; }
public string ProjectMonth { get; set; }
public string Week1 { get; set; }
public string Week2 { get; set; }
public string Week3 { get; set; }
public string Week4 { get; set; }
public string Week5 { get; set; }
public IEnumerable<LoggedBugs> LoggedBugsCount { get; set; }
public IEnumerable<LoggedBugs> ClosedBugs { get; set; }
}
It can be problem with ProjectYear and ProjectMonth. At database side they are int, so at .NET side they would propably unboxed as System.Int32. In your entity they are string.
Try convert it to varchar in your sp or change types in entity to int.
Change your ProjectYear and ProjectMonth properties to type int in LoggedBugs class. Your sql returns them as int, see YEAR SQL MSDN description since YEAR and MONTH sql functions both return values of type int. Your C# code expects a string, so you get a type mismatch exception.