Refactoring a (simple) statement - c#

I want to refactor a method but I'm not too sure how to but I know you can do it.
My current method:
public bool AdminShutdown(int accountID, int accountPin)
{
var status = false;
if (accountID == AdminLogin && accountPin == AdminPin)
{
status = true;
}
return status;
}
I think it should be something like
var status = (accountID == AdminLogin) && (accountPin == AdminPin) but that doesn't work ( Operator '&&' cannot be applied to operands of type 'bool' and 'int').
Suggestions?
P.S. Would this code work?
var tempReturnPerson = AccountHoldersList.Single((x => x.AccountNumber == accountId));
instead of:
public AccountHolders ReturnAccountInfo(int accountId)
{
//use linq to do this later
var returnPerson = new AccountHolders();
foreach (var person in AccountHoldersList)
{
if (accountId == person.AccountNumber)
{
returnPerson = person;
break;
}
}
return returnPerson;
}

if AdminLogin and AdminPin are int, than
public bool AdminShutdown(int accountID, int accountPin)
{
return (accountID == AdminLogin && accountPin == AdminPin);
}
The error message you get make me think you may have used an = instead of an ==
EDIT
For your second question
var tempReturnPerson = AccountHoldersList.Single((x => x.AccountNumber == accountId));
should rather be
var tempReturnPerson = AccountHoldersList.FirstOrDefault(x => x.AccountNumber == accountId) ?? new AccountHolders();
If you want the same result as your method.

"(accountID == AdminLogin && accountPin == AdminPin)" can simply be evaluated to a bool
public bool AdminShutdown(int accountID, int accountPin)
{
return (accountID == AdminLogin && accountPin == AdminPin)
}

Related

Get result using condition not works properly (C#)

I trying to get data from datatabase and assign it to list
Here is 2 conditions. 1 - I have only categoryId and 2 - I have category and subcategoryId
I wrote code like this
public async Task<List<TimelineItemDto>> GetFilteredClasses(int? categoryId, int? subcategoryId)
{
List<TimelineItemDto> filteredClasses;
if (categoryId != null)
{
filteredClasses = await _context.Events
.Where(x => x.CategoryId == categoryId && x.EventType == EntityType.Class)
.ProjectTo<TimelineItemDto>()
.ToListAsync();
}
if (categoryId != null && subcategoryId != null)
{
filteredClasses = await _context.Events
.Where(x => x.CategoryId == categoryId && x.SubcategoryId == subcategoryId &&
x.EventType == EntityType.Class)
.ProjectTo<TimelineItemDto>()
.ToListAsync();
}
else
{
filteredClasses = await _context.Events.Where(x =>
x.EventType == EntityType.Class).ProjectTo<TimelineItemDto>()
.ToListAsync();
}
return filteredClasses;
}
but at first if I got this
A second if and at else all okay and it's executed and filling list
How I can solve this?
Well I would do something like below :
public async Task<List<TimelineItemDto>> GetFilteredClasses(int? categoryId, int? subcategoryId)
{
var filteredClasses = _context.Events.Where(x => x.EventType == EntityType.Class);
if (categoryId != null)
{
filteredClasses = filteredClasses.
.Where(x => x.CategoryId == categoryId);
}
if (categoryId != null && subcategoryId != null)
{
filteredClasses = filteredClasses.Where(x => x.SubcategoryId == subcategoryId );
}
return await filteredClasses.ProjectTo<TimelineItemDto>()
.ToListAsync();;
}
This way you will avoid materializing multiple queries.
You should update the condition flow as below:
if (categoryId != null && subcategoryId != null)
{
...
}
else if (categoryId != null)
{
...
}
else
{
...
}
With above, the filteredClasses will not be overridden by last else condition. Your current code first evaluate if and then if & else. Both are different code blocks and last else is always getting executed.

Getting error in LINQ query to sqlite

I'm trying to make login query in sqlite but can't convert AsyncTableQuery in boolean
public bool queryLogIn(string userNameLogIn,string passwordLogIn)
{
var query=database.Table<Users>().Where(i => i.UserName == userNameLogIn && i.Password == passwordLogIn);
if (query == true)//There is error
{
return true;
}
else
{
return false;
}
}
You can use FirstOrDefault function for login is success.
public bool queryLogIn(string userNameLogIn,string passwordLogIn)
{
var query=database.Table<Users>().FirstOrDefault(i => i.UserName == userNameLogIn && i.Password == passwordLogIn);
if (query == null)//There is error
{
return false;
}
else
{
return true;
}
}
Where returns an iqueryable of Users. You need Any instead which Determines whether any element of a sequence satisfies a condition and since it's return type is bool you can use it in your if statement:
var query=database.Table<Users>().Any(i => i.UserName == userNameLogIn
&& i.Password == passwordLogIn);
EDIT: Or use Any in your if:
var query=database.Table<Users>().Where(i => i.UserName == userNameLogIn
&& i.Password == passwordLogIn);
if (query.Any())
{
return true;
}

LINQ doesn't accept static function in a predicate: LINQ to Entities does not recognize the method

I know this question looks like a duplicate but it seems like each case has it's own solution and I can't find the right explanation for this Exception:
LINQ to Entities does not recognize the method 'Boolean
DateReservationOnTheSameWeek(System.DateTime)' method, and this method
cannot be translated into a store expression.
I just want to compare if two dates are on the same iso week of year, here's my code:
public class Reservation
{
public DateTime DateReservation { get; set; }
// other methods and properties
public static bool IsOnQuota(Reservation item)
{
using (var ctx = new SchedulingToolContext())
{
float qteSem = ctx.Reservations.Where(k => k.CltNameAlpha == item.CltNameAlpha
&& k.DateReservation.Year == item.DateReservation.Year
&& item.DateReservationOnTheSameWeek(k.DateReservation) // this causes the exception
).Sum(k => k.Qte);
var q = ctx.Quotas.Where(k => k.Id == item.IdQuota).FirstOrDefault();
return q.QteMaxJour >= item.Qte && q.QteMaxSemaine >= qteSem;
}
}
private static int GetIso8601WeekOfYear(DateTime time)
{
DayOfWeek day = System.Globalization.CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(time);
if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
{
time = time.AddDays(3);
}
return System.Globalization.CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(time, System.Globalization.CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
}
private bool DateReservationOnTheSameWeek(DateTime date)
{
return GetIso8601WeekOfYear(this.DateReservation) == GetIso8601WeekOfYear(date);
}
}
I can't figure out why this predicate fails.
EDIT: I can't calculate the predicate out of the query because, it depends on k that is part of the lambda function.
Perhaps using SqlFunctions.DatePart and ISO_WEEK will help
using (var ctx = new SchedulingToolContext())
{
float qteSem = ctx.Reservations.Where(k => k.CltNameAlpha == item.CltNameAlpha
&& k.DateReservation.Year == item.DateReservation.Year
&& SqlFunctions.DatePart("isowk", this.DateReservation) == SqlFunction.DatePart("isowk", k.DateReservation)
).Sum(k => k.Qte);
var q = ctx.Quotas.Where(k => k.Id == item.IdQuota).FirstOrDefault();
return q.QteMaxJour >= item.Qte && q.QteMaxSemaine >= qteSem;
}

Paging Error: The method 'Skip' is only supported for sorted input in LINQ to Entities. The method 'OrderBy' must be called before the method 'Skip'

I have this following codes. I did not use a sorting just with the filtering or searching of information. I did not use skip method also. Please see codes below.
public ActionResult Index(string currentFilter=null, string search=null, string searchBy=null, int? page=1)
{
var student = from d in db.Student_vw
where d.is_active == true
select d;
if (searchBy == "default")
{
student = student.OrderByDescending(x => x.ID_Number);
}
//searching of an item
if (!String.IsNullOrEmpty(search))
{
student = student.Where(x => x.ID_Number.Contains(search) || x.student_fname.Contains(search)
|| x.student_lname.Contains(search) || x.section_name.Contains(search) || x.course_name.Contains(search)
|| x.student_address.Contains(search) || x.batch_name.Contains(search) || x.adviser_fname.Contains(search) || x.adviser_lname.Contains(search) || x.student_email_add.Contains(search));
}
else {
student = student.OrderByDescending(x => x.ID_Number);
}
ViewBag.CurrentFilter = search;
int pageSize = 25;
int pageNumber = (page ?? 1);
var returnMe = student.ToPagedList(pageNumber, pageSize);
return View(returnMe);
}
Thanks in advance for the help.
in your code, when search having value, students not ordered. do as below
public ActionResult Index(string currentFilter=null, string search=null, string searchBy=null, int? page=1)
{
var student = from d in db.Student_vw
where d.is_active == true
select d;
//if (searchBy == "default")
//{
// student = student.OrderByDescending(x => x.ID_Number);
//}
//searching of an item
if (!String.IsNullOrEmpty(search))
{
student = student.Where(x => x.ID_Number.Contains(search) || x.student_fname.Contains(search)
|| x.student_lname.Contains(search) || x.section_name.Contains(search) || x.course_name.Contains(search)
|| x.student_address.Contains(search) || x.batch_name.Contains(search) || x.adviser_fname.Contains(search) || x.adviser_lname.Contains(search) || x.student_email_add.Contains(search));
}
//else {
// student = student.OrderByDescending(x => x.ID_Number);
//}
ViewBag.CurrentFilter = search;
int pageSize = 25;
int pageNumber = (page ?? 1);
var returnMe = student.OrderByDescending(x => x.ID_Number).ToPagedList(pageNumber, pageSize);
return View(returnMe);
}
#Jen- You need to use OrderBy before student.ToPageList(pageNumber, pageSize)
SQL doesn't guarantee the order of results unless you give it an order by, so using Take or Skip (which PagedList does internally) without an order by doesn't make any logical sense and in theory could give you totally different results each time.
The way you have written your logic you can fall through without every hitting on of the order by statements.

LINQ query AND & OR

I'm starting my journey with .NET and I need a little help.
I will describe my situation by example what I have and what I need to do but I don't know how to do that.
So I have a class like this
public class Ban
{
public int ID { get; set; }
public string Nick { get; set; }
public string IP { get; set; }
public string GroupName { get; set; }
}
and variable bans which is IQueryable
Then in method of signature
public IEnumerable<Ban> FindBans(Ban filter);
I need to search through that bans variable;
How I search now
public IEnumerable<Ban> FindBans(Ban filter)
{
var bans = GetBansQueryable();
if (!string.IsNullOrWhiteSpace(filter.GroupName))
{
bans = bans.Where(b => b.GroupName == filter.GroupName);
}
if (!string.IsNullOrWhiteSpace(filter.Nick))
{
bans = bans.Where(b => b.Nick == filter.Nick);
}
if (!string.IsNullOrWhiteSpace(filter.IP))
{
bans = bans.Where(b => b.IP == filter.IP);
}
return bans.AsEnumerable();
}
Which filters with AND. SQL query part will be like this
... WHERE group_name = 'abc' AND nick = 'def' AND ip = 'ghi';
What I need is
... WHERE group_name = 'abc' AND (nick = 'def' OR ip = 'ghi');
All of this need to be dynamic (if we don't pass GroupName don't filter by it etc.)
I have no idea how I can achieve that beside making this dynamics manualy like
if (!string.IsNullOrWhiteSpace(filter.GroupName) &&
string.IsNullOrWhiteSpace(filter.Nick) &&
string.IsNullOrWhiteSpace(filter.IP))
{
bans = bans.Where(b => b.GroupName == filter.GroupName);
}
else if (!string.IsNullOrWhiteSpace(filter.GroupName) &&
!string.IsNullOrWhiteSpace(filter.Nick) &&
string.IsNullOrWhiteSpace(filter.IP))
{
bans = bans.Where(b => b.GroupName == filter.GroupName && b.Nick == filter.Nick);
}
else if (!string.IsNullOrWhiteSpace(filter.GroupName) &&
!string.IsNullOrWhiteSpace(filter.Nick) &&
!string.IsNullOrWhiteSpace(filter.IP))
{
bans = bans.Where(b => b.GroupName == filter.GroupName && (b.Nick == filter.Nick || b.IP == filter.IP));
}
and so on... and now add another variable to Ban.
I think you can simplify you entire constraint like this:
bans = bans.Where(b => ( string.IsNullOrWhiteSpace(filter.GroupName) || b.GroupName == filter.GroupName )
&&
( ( string.IsNullOrWhiteSpace(filter.Nick) || b.Nick == filter.Nick )
||
( string.IsNullOrWhiteSpace(filter.IP) || b.IP == filter.IP )
)
);
You probably would like to look at Scott Hansleman blog post on dynamic sql, predicate builder and linqkit:
The Weekly Source Code 48 - DynamicQueryable makes custom LINQ expressions easier
Otherwise there is a very nice blog post about using dynamic filter with Kendo UI grid and Web Api:
Kendo UI Open Sources Dynamic LINQ Helpers
You could special-case the situation where both nick and ip are known:
public IEnumerable<Ban> FindBans(Ban filter)
{
var bans = GetBansQueryable();
if (!string.IsNullOrWhiteSpace(filter.GroupName))
{
bans = bans.Where(b => b.GroupName == filter.GroupName);
}
if (!string.IsNullOrWhiteSpace(filter.Nick) && !string.IsNullOrWhiteSpace(filter.IP))
{
bans = bans.Where(b => b.Nick == filter.Nick || b.IP == filter.IP);
}
else if (!string.IsNullOrWhiteSpace(filter.Nick))
{
// filter.IP is empty
bans = bans.Where(b => b.Nick == filter.Nick);
}
else if (!string.IsNullOrWhiteSpace(filter.IP))
{
// filter.Nick is empty
bans = bans.Where(b => b.IP == filter.IP);
}
return bans.AsEnumerable();
}

Categories

Resources