what cast is missing in linq syntax? - linq

tblUserRole Permission =
(oCurrenUserPermission.GetPermission(Convert.ToString(Session["Navigation"])));
if (Permission.IsInsert == 1)
{
}
public IQueryable GetPermission(string sPageName)
{
IQueryable query;
#region MyRegion
query = from r in this.Context.tblUserRoles
join p in this.Context.tblPageInfos on r.PageID equals p.PageID
where r.Record_Status == 2 && p.PageName == sPageName
select r;
return query;
#endregion
}
Above syntax show the bellow error:
Error 1 Cannot implicitly convert type 'System.Linq.IQueryable' to 'AkijBeverage.ServiceObject.tblUserRole'. An explicit conversion exists (are you missing a cast?) E:\Project-Akij\09-July-2010\AkijBeverage\AkijBeverage\SecurityUserControls\UCUserRole.ascx.cs 63 43 AkijBeverage
How to solve this ?

As far as I can tell, that query is just not compatible with tblUserRole.
It's going to return a IEnumereable<bool> instead of a tblUserRole.
The real problem is that you are selecting the IsInsert in two different spots: In the query, and again in the if()
The easiest way would be just return the full tblUserRole object:
return (from r in this.Context.tblUserRoles
join p in this.Context.tblPageInfos on r.PageID equals p.PageID
where r.Record_Status == 2 && p.PageName == sPageName
select r).SingleOrDefault();

Currently you're returning a query - not a single item. What do you want to return?
Here's one option, for example:
public tblUserRole GetPermission(string sPageName)
{
return (from r in this.Context.tblUserRoles
join p in this.Context.tblPageInfos on r.PageID equals p.PageID
where r.Record_Status == 2 && p.PageName == sPageName
select r).FirstOrDefault();
}
This will return the first matching role, or null if there aren't any.
If you do want to return a query, it would be better as a strongly typed IQueryable<T>:
public IQueryable<tblUserRole> GetPermissions(string sPageName)
{
return from r in this.Context.tblUserRoles
join p in this.Context.tblPageInfos on r.PageID equals p.PageID
where r.Record_Status == 2 && p.PageName == sPageName
select r;
}
Then you'd need to change your calling code to something like this:
tblUserRole Permission
oCurrenUserPermission.GetPermissions(Convert.ToString(Session["Navigation"]))
.FirstOrDefault();

The problem is you have an IQueryable and are attempting to assign to a "Type" without a cast.
Either change your method to:
public IQueryable<tblUserRole > GetPermission(string sPageName)
and then do (First/FirstOrDefault/Single/etc..)
oCurrenUserPermission.GetPermission(...).FirstOrDefault();
Or cast it and cross your fingers and select one.
(tblUserRole)oCurrenUserPermission.GetPermission(...).FirstOrDefault();
Side Note
I would suggest you work on naming your code in a more friendly maner. No need to prepend the "type" at the beginning. For example a possible better way to name everything:
string navigationValue = Convert.ToString(Session["Navigation"]);
UserRole permission =
currentUserPermission.GetPermission(navigationValue ).FirstOrDefault();
//If this isn't a boolean i would consider using one
if (permission.IsInsert == 1)
{
}
public IQueryable<UserRole> GetPermission(string sPageName)
{
#region MyRegion
var query = from r in this.Context.UserRoles
join p in this.Context.PageInformation on r.PageID equals p.PageID
where r.Record_Status == 2 && p.PageName == sPageName
select r;
return query;
#endregion
}

Related

LINQ EF AND VS2017

I wrote a query and worked on LINQPAD
from x in FacilityData
from y in FavInformation
where y.UserID == 1 && x.ID == y.FacilityID
select new
{
xID = x.ID,
xDistrictName = (from y in _Ilcelers
where y.ID == x.DistrictID
select y.IlceAd).FirstOrDefault(),
xName = x.Name,
Value = (from o in Tags
from p in Table_tags
where o.Prefix != null && o.Prefix == p._NAME && o.Facility == y.FacilityID
orderby p.İd descending
select new
{
FType = o.TagType,
Name = o.TagsName,
Value = p._VALUE,
Time = p._TIMESTAMP
}).Take(Tags.Count(h => h.Facility == y.FacilityID))
}
result
the result is perfect
but does not work in visual studio,
Value = (from o in DB.Tags
from p in DB.table_tags
where o.Prefix != null && o.Prefix == p.C_NAME && o.Facility == 11
orderby p.id descending
select new
{
FType=o.TagType,
Name = o.TagsName,
Value = p.C_VALUE,
Time = p.C_TIMESTAMP
}).Take(Tags.Count(h => h.Facility == y.FacilityID))
and it gives an error.
I guess the part with .Take() doesn't work because it's linq to EF.
error:
Limit must be a DbConstantExpression or a Db Parameter Reference Expression. Parametre name: count]
error image
thank you have a good day
Not sure but I will just throw it in. If you are talking about linq to ef/sql, it is possible they dont know a thing about C#. If take() would be the problem try to get the select result local first by doing .tolist(). Afterwards use your take funtion.
.ToList().Take(Tags.Count(h => h.Facility == y.FacilityID))

How to compare IEnumerable<string> for null in Linq query

For the following query:
var result = from sch in schemeDashboard
join exp in Expenditure on sch.schemeId equals exp.SchemeCode
into SchExpGroup
where sch.SectorDepartmentId == selectedDepartmentId &&
sch.YearCode == StateManager.CurrentYear
orderby sch.ADPId
select new
{
ModifiedAmounts = SchExpGroup.Select(a => a.ModifiedAmounts),
ProjectName = sch.schemeName,
ADPNo = sch.ADPId,
Allocation = sch.CurrentAllocation,
Expenditures = from expend in SchExpGroup
where expend.YearCode == StateManager.CurrentYear &&
expend.DepartmentId == selectedDepartmentId &&
InvStatus.Contains(expend.Status)
orderby expend.ADPId
group expend by expend.InvoiceId
};
I want to filter the above query on a condition so that result gives only those records where "ModifiedAmounts" are not null. I have tried as follow:
if (rbList2.SelectedIndex == 6)
{
result = result.Where(a => a.ModifiedAmounts != null));
}
but this gives error as:
Cannot compare elements of type
'System.Collections.Generic.IEnumerable`1'. Only primitive types,
enumeration types and entity types are supported.
Any suggestions as I am lost as how to rephrase the filtered query.
I think the problem is that ModifiedAmounts will never be null. Select will return an empty list. Unless SchExpGroup is null in which case you will get a null reference exception.
Try changing your code to
result = result.Where(a => a.ModifiedAmounts.Any());
if (rbList2.SelectedIndex == 6)
{
result = result.Where(a => a.!ModifiedAmounts.Any());
}

Creating reusable chunks of LINQ to SQL

I am trying to break up linq to sql queries to make them a bit more readable.
Say I want to return all orders for product which in the previous year had more than 100 orders. I have this query:
from o in _context.Orders
where (from o1 in _context.Orders
where o1.Year == o.Year - 1 && o1.Product == o.Product
select o1).Count() > 100
select o;
What I'd like to be able to do is to put the nested query in a reusable function:
private IQueryable<Order> LastSeasonOrders(Order order)
{
return (from o in _context.Orders
where o.Year == order.Year - 1 && o.Product == order.Product
select o);
}
which then lets me change the original query to:
from o in _context.Orders
where LastSeasonOrders(o).Count() > 100
select o;
This doesn't work however with an exception saying that the method call cannot be translated to SQL when the query is run.
Any quick tips on the correct way to achieve this?
What about something like -
void Main()
{
TypedDataContext _context = ...
var query =
(
from o in _context.Orders
where LastSeasonOrders(_context , o).Count() > 100
select o
);
...
}
public static Func<TypedDataContext, Order, IQueryable<Order>>
LastSeasonOrders = CompiledQuery.Compile
(( TypedDataContext _context, Order order) =>
from o in _context.Orders
where o.Year == order.Year - 1 && o.Product == order.Product
select o
);
?
It would be best to verify that the sql produced is the same as that produced by your original query.
I am just shooting from the hip but have you tried change return type of LastSeasonOrders to IQueryable<Order>?

How to handle no results in LINQ?

in this example code
public Company GetCompanyById(Decimal company_id)
{
IQueryable<Company> cmps = from c in db.Companies
where c.active == true &&
c.company_id == company_id
select c;
return cmps.First();
}
How should I handle if there is no data in cmps?
cmps will never be null, so how can I check for non existing data in a LINQ Query?
so I can avoid this
'cmps.ToList()' threw an exception of type ... {System.NullReferenceException}
when transforming it into, for example, a List
GetCompanyById(1).ToList();
Do I always need to wrap it up in a try catch block?
You can use Queryable.Any() (or Enumerable.Any()) to see if there is a member in cmps. This would let you do explicit checking, and handle it however you wish.
If your goal is to just return null if there are no matches, just use FirstOrDefault instead of First in your return statement:
return cmps.FirstOrDefault();
What about applying .Any or .Count() ?
Here's an example on MSDN
List<int> numbers = new List<int> { 1, 2 };
bool hasElements = numbers.Any();
Console.WriteLine("The list {0} empty.",
hasElements ? "is not" : "is");
Or just use the ?: operator
return myExample.Any() ? myExample.First() : null;
This will return the first one if there is one, or null if there isn't:
return (from c in db.Companies
where c.active == true &&
c.company_id == company_id
select c).FirstOrDefault();
Try return cmps.Count()==0?null:cmp.First()
That way if it is null it will simply return a null Company and if its not then it will return the first one in the list.
Check out http://en.wikipedia.org/wiki/Ternary_operation
var context = new AdventureWorksLT2008Entities();
var cust = context.Customers.Where(c => c.CustomerID == 1);
if (cust.Any())
{
Customer c = cust.First();
}

conditional assignments in Linq to SQL methods

How do I do something like the following, assinging new values based on condition within a linq method but keeping all results.
int x= 100;
var results= from r in Results where r.id==id select r
{ if r.value==x set r.result="Found"}
You're not really meant to - ideally queries shouldn't have side effects. I mean you can do:
var results = Results.Where(r => r.id == id)
.Select(r => {
if (r.value == x)
{
r.result = "Found";
}
return r;
};
I'd generally try not to though...
Note that this really won't work in LINQ to SQL etc.
It's probably better to make a second pass so you can keep your query clean and side-effect-free.
int x = 100;
List<Result> results = (from r in Results
where r.id == id
select r).ToList();
results.ForEach(r => r.result = r.value == x ? "Found" : "Not Found");
Linq should not be used in that way. I would iterate over the results of the query and then change them.
var results= from r in Results where r.id==id select r;
foreach (var r in results.ToList()) { if (r.value==x) r.result="Found"; }

Resources