MVC3 Multiple Conditions in where Clause - asp.net-mvc-3

I have the following in my Controller
var workshop = registerDB.Workshops.Single(w => w.WorkshopID == id);
ViewBag.Enrollments = registerDB.Carts.Where(x => x.Username.Equals(User.Identity.Name));
and this in my view
#{
//var carts = Model.Carts.Where(x => x.Username.Equals(User.Identity.Name));
var carts = ViewBag.Enrollments;
var timeSlot = Model.TimeSlot;
}
#{
foreach (var item in carts)
{
if (item != null)
{
if (timeSlot == item.Workshop.TimeSlot)
{
<h3>#timeSlot</h3>
}
}
else
{
<h3>Does not Exist</h3>
}
}
}
each time ViewBag.Enrollments = registerDB.Carts.Where(x => x.Username.Equals(User.Identity.Name)); returns no results, I get an error saying System.InvalidOperationException: There is already an open DataReader associated with this Command which must be closed first. and this line is highlighted
if (timeSlot == item.Workshop.TimeSlot)

Try calling .ToList() in the controller to eagerly fetch the results:
ViewBag.Enrollments = registerDB
.Carts
.Where(x => x.Username.Equals(User.Identity.Name))
.ToList();

You are checking that item != null but not that item.Workshop != null before trying to use it. It would appear that is perhaps the error, but why it's raising InvalidOperationException rather than NullReferenceException I don't know.
Try:
if (item != null && item.Workshop != null)
{
if (timeSlot == item.Workshop.TimeSlot)
{
<h3>#timeSlot</h3>
}
}

Could you put the single call in your model:
workshops workshop = registerDB.Workshops.Single(w => w.WorkshopID == id);
And then in your controller set the ViewBag:
try
{
ViewBag.Enrollments = workshop.Carts.Where(x => x.Username.Equals(User.Identity.Name));
}
catch
{
ViewBag.Enrollments = "There are no results";
}

Related

Linq To Select All controls where DI contains some text from ControlCollection

Linq has always befuddled me. I am trying to extract all controls from an ASP.Net form page where the ID of the control contains a specific string. The control collection is hierarchical and I want to return any matching controls from all levels. Am I anywhere in the ballpark here? I could really use some help/education. The collection parameter is the collection of controls from the page and controlID is the text I am searching for.
public static Control FindControlsByControlID(ControlCollection collection, string controlID)
{
IEnumerable<Control> controls = collection.Cast<Control>();
IEnumerable<Control> matchedControls = controls
.SelectMany(p => p.Controls.Cast<Control>()
.SelectMany(c => c.Controls.Cast<Control>())
.Where(d => d != null ? d.ID != null ? d.ID.Contains(controlID) : false : false))
.Where(a => a != null ? a.ID != null ? a.ID.Contains(controlID) : false : false);
ConcurrentQueue<Control> cq;
if (matchedControls != null)
cq = new ConcurrentQueue<Control>(matchedControls);
else
return null;
...
Thanks in advance!
Use an extension method to get all child controls:
public static class ControlExt {
public static IEnumerable<Control> AndSubControls(this Control aControl) {
var work = new Queue<Control>();
work.Enqueue(aControl);
while (work.Count > 0) {
var c = work.Dequeue();
yield return c;
foreach (var sc in c.Controls.Cast<Control>()) {
yield return sc;
if (sc.Controls.Count > 0)
work.Enqueue(sc);
}
}
}
}
Now you can test all the subcontrols in your ControlCollection:
IEnumerable<Control> matchedControls = controls.SelectMany(c => c.AndSubControls())
.Where(a => a != null && a.ID != null && a.ID.Contains(controlID));

How to check if the user doesn't select any item in the list?

I have a list view that list the activities. I have a way to get the selected values. What I don't know is how can I check if the user doesn't select any items from the list. How can I do this?
This is how I populate my list this will return at least 5-20 activities:
public void Get_Activities()
{
try
{
var db = DependencyService.Get<ISQLiteDB>();
var conn = db.GetConnection();
var getActivity = conn.QueryAsync<ActivityTable>("SELECT * FROM tblActivity WHERE Deleted != '1' ORDER BY ActivityDescription");
var resultCount = getActivity.Result.Count;
if (resultCount > 0)
{
var result = getActivity.Result;
lstActivity.ItemsSource = result;
lstActivity.IsVisible = true;
}
else
{
lstActivity.IsVisible = false;
}
}
catch (Exception ex)
{
//Crashes.TrackError(ex);
}
}
And this is how I get the values of the selected items on my list:
foreach(var x in result)
{
if (x.Selected)
{
// do something with the selected items
}
}
My question is like this
if(list.selecteditemcount == 0){
DisplayAlert("Error","Please select atleast 1 item","Ok");
}
In xamarin projects you can use Linq (using System.Linq). With Linq it's really easy to filter your list like that:
if(!list.Any(x => x.Selected == true))
{
// DisplayAlert...
}
This basically checks if any of your items has the value Selected='true'
Or without Linq you can do something like this:
if(list.FindAll(x => x.Selected).Count() == 0)
{
//DisplayAlert...
}
Use this
if (result.Any(x => x.Selected))
{
}
else
{
await DisplayAlert("Application Error", "Please choose at least one(1) activity", "Ok");
}

LINQ query fails with nullable variable ormlite

I'm trying to write following LINQ query using ServiceStack Ormlite.
dbConn.Select<Product>(p => p.IsActive.HasValue && p.IsActive.Value)
Here, Product is my item class and "IsActive" is Nullable Bool property in that class. When this line executes it always throws "InvalidOperationException" with the message
variable 'p' of type '' referenced from scope '', but it is not defined
I tried different variants as following but still same exception result
dbConn.Select<Product>(p => p.IsActive.HasValue == true && p.IsActive.Value == true)
dbConn.Select<Product>(p => p.IsActive != null && p.IsActive.Value == true)
But if I just write
dbConn.Select<Product>(p => p.IsActive.HasValue)
then it works.
I'm puzzled what is the problem? Is this servicestack ormlite issue?
My answer can handle Nullable value like "value" and "HasValue" with servicestack ormlite. And But also with datetime nullable ,like 'createdate.value.Year'.
you must change two place.
modify VisitMemberAccess method:
protected virtual object VisitMemberAccess(MemberExpression m)
{
if (m.Expression != null)
{
if (m.Member.DeclaringType.IsNullableType())
{
if (m.Member.Name == nameof(Nullable<bool>.Value))
return Visit(m.Expression);
if (m.Member.Name == nameof(Nullable<bool>.HasValue))
{
var doesNotEqualNull = Expression.NotEqual(m.Expression, Expression.Constant(null));
return Visit(doesNotEqualNull); // Nullable<T>.HasValue is equivalent to "!= null"
}
throw new ArgumentException(string.Format("Expression '{0}' accesses unsupported property '{1}' of Nullable<T>", m, m.Member));
}
if (m.Member.DeclaringType == typeof(DateTime))
{
var ExpressionInfo = m.Expression as MemberExpression;
if (ExpressionInfo.Member.DeclaringType.IsNullableType())
{
if (ExpressionInfo.Member.Name == nameof(Nullable<bool>.Value))
{
var modelType = (ExpressionInfo.Expression as MemberExpression).Expression.Type;
var tableDef = modelType.GetModelDefinition();
var columnName = (ExpressionInfo.Expression as MemberExpression).Member.Name;
var QuotedColumnName = GetQuotedColumnName(tableDef, columnName);
if (m.Member.Name == "Year")
{
return new PartialSqlString(string.Format("DATEPART(yyyy,{0})", QuotedColumnName));
}
if (m.Member.Name == "Month")
return new PartialSqlString(string.Format("DATEPART(mm,{0})", QuotedColumnName));
}
if (ExpressionInfo.Member.Name == nameof(Nullable<bool>.HasValue))
{
var doesNotEqualNull = Expression.NotEqual(ExpressionInfo.Expression, Expression.Constant(null));
return Visit(doesNotEqualNull); // Nullable<T>.HasValue is equivalent to "!= null"
}
}
else
{
var modelType = ExpressionInfo.Expression.Type;
var tableDef = modelType.GetModelDefinition();
var columnName = ExpressionInfo.Member.Name;
var QuotedColumnName = GetQuotedColumnName(tableDef, columnName);
if (m.Member.Name == "Year")
return new PartialSqlString(string.Format("DATEPART(yyyy,{0})", QuotedColumnName));
if (m.Member.Name == "Month")
return new PartialSqlString(string.Format("DATEPART(mm,{0})", QuotedColumnName));
}
}
if (m.Expression.NodeType == ExpressionType.Parameter || m.Expression.NodeType == ExpressionType.Convert)
{
var propertyInfo = (PropertyInfo)m.Member;
var modelType = m.Expression.Type;
if (m.Expression.NodeType == ExpressionType.Convert)
{
var unaryExpr = m.Expression as UnaryExpression;
if (unaryExpr != null)
{
modelType = unaryExpr.Operand.Type;
}
}
var tableDef = modelType.GetModelDefinition();
if (propertyInfo.PropertyType.IsEnum)
return new EnumMemberAccess(
GetQuotedColumnName(tableDef, m.Member.Name), propertyInfo.PropertyType);
return new PartialSqlString(GetQuotedColumnName(tableDef, m.Member.Name));
}
}
var member = Expression.Convert(m, typeof(object));
var lambda = Expression.Lambda<Func<object>>(member);
var getter = lambda.Compile();
return getter();
}
modify VisitLambda method :
protected virtual object VisitLambda(LambdaExpression lambda)
{
if (lambda.Body.NodeType == ExpressionType.MemberAccess && sep == " ")
{
MemberExpression m = lambda.Body as MemberExpression;
if (m.Expression != null)
{
string r = VisitMemberAccess(m).ToString();
if (m.Member.DeclaringType.IsNullableType())
return r;
return string.Format("{0}={1}", r, GetQuotedTrueValue());
}
}
return Visit(lambda.Body);
}
This is nature of the Linq. In order to achieve what you need, you will need to use two where closes:
dbConn.Where<Product>(p => p.IsActive.HasValue).Where(p=>p.Value==true);

Ef 6 RemoveRange in Linq

IQueryable<PortServicesTariffDetail> detalis = _context.PortServicesTariffDetails
.Where(w => w.PortServicesTariffId == TariffId &&
w.PortServicesTariffDetailId == DetailId);
if (detalis.Count() > 0)
{
var mydetial = detalis.GroupBy(g => new { g.StartRate,g.EndRate }).AsQueryable();
_context.PortServicesTariffDetails.RemoveRange(mydetial.AsQueryable());
_context.SaveChanges();
}
Depends on the start and end rate remove range, I have raise some issue like anonymous type. so what can I do???
Argument 1: cannot convert from 'System.Linq.IQueryable>' to 'System.Collections.Generic.IEnumerable'
Try this
foreach(var x in mydetial)
{
_context.PortServicesTariffDetails.RemoveRange(x.ToList());
}
_context.SaveChanges();
But I don't understand why you're grouping everything to remove it?
Try this :
var detalis = _context.PortServicesTariffDetails
.Where(w => w.PortServicesTariffId == TariffId &&
w.PortServicesTariffDetailId == DetailId).ToList();
if (detalis.Count() > 0)
{
var mydetial = detalis.GroupBy(g => new { g.StartRate,g.EndRate }).AsQueryable();
_context.PortServicesTariffDetails.RemoveRange(mydetial.AsQueryable());
_context.SaveChanges();
}
I think there is no need to use Group by,
You can simply use RemoveRange
_context.PortServicesTariffDetails.RemoveRange(detalis);
_context.SaveChanges();

Use method in entity framework query

Is there anyway around this error? I'd like to reuse the same lamba expression in other queries instead of having duplication. Can LinqKit or other linq expression do this?
Error
LINQ to Entities does not recognize the method 'Boolean GetEvent(Tournaments.Data.Entities.Event, System.String)' method, and this method cannot be translated into a store expression.
Code
public MobileEventDetailModel GetDetails(string applicationId)
{
var #event = (from e in _eventsRepository.DataContext.Events.Include(q => q.Assets.Select(a => a.Asset))
where GetEvent(e, applicationId)
select new
{
e.Id,
e.EventParent.Name,
LogoId = (from a in e.Assets
where a.Type == EventAssetType.Logo
select a.AssetId).FirstOrDefault()
}).FirstOrDefault();
return new MobileEventDetailModel
{
Id = #event.Id,
Name = #event.Name,
Logo = string.Format("{0}{1}{2}", Config.BaseUrl, Config.ImagesPath, #event.LogoId)
};
}
public bool GetEvent(Event #event, string applicationId)
{
return #event.Active && #event.Visible && #event.MobileEventApplications.Any(m =>
m.MobileApplication.ApplicationId == applicationId &&
(!m.MobileApplication.ActivationLength.HasValue || EntityFunctions.AddDays(DateTime.Now, 1) < EntityFunctions.AddMonths(m.MobileApplication.DateActivated, m.MobileApplication.ActivationLength.Value)));
}
You need to use an Expression:
public MobileEventDetailModel GetDetails(string applicationId)
{
var event = _eventsRepository.DataContext.Events.Include(q => q.Assets.Select(a => a.Asset))
.Where(GetEvent(applicationId))
.Select(a => new
{
a.Id,
a.EventParent.Name,
LogoId = (from b in a.Assets
where b.Type == EventAssetType.Logo
select b.AssetId).FirstOrDefault()
}).FirstOrDefault();
return new MobileEventDetailModel
{
Id = event.Id,
Name = event.Name,
Logo = string.Format("{0}{1}{2}", Config.BaseUrl, Config.ImagesPath, event.LogoId)
};
}
public Expression<Func<Event, bool>> GetEvent(int applicationId)
{
return = a => a.Active
&& a.Visible
&& a.MobileEventApplications
.Any(m => m.MobileApplication.ApplicationId == applicationId
&& (!m.MobileApplication.ActivationLength.HasValue
|| EntityFunctions.AddDays(DateTime.Now, 1)
< EntityFunctions
.AddMonths(m.MobileApplication.DateActivated, m.MobileApplication.ActivationLength.Value)
)
);
}
Update: Sorry it was late the other night, the changed version is hopefully more what you were looking for.

Resources