this is my original query
public UserChallenge GetUserChallenge(int userId, int challengeId)
{
var result = from userChallenge in DataContext.UserChallenges
where userChallenge.UserId == userId && userChallenge.ChallengeId == challengeId
select userChallenge;
here is the modified query
var result = from userChallenge in DataContext.UserChallenges
where userChallenge.ChallengeId == challengeId
select userChallenge;
there is more than 1 userChallenge's that hold that ChallengeId. How can I select only the first one ?
Check out FirstOrDefault.
var result = (from userChallenge in DataContext.UserChallenges
where userChallenge.UserId == userId && userChallenge.ChallengeId == challengeId
select userChallenge).FirstOrDefault();
But in the long run, it might be more helpful to determine a way to uniquely identify your records.
You can use First or FirstOrDefault to get the first item in the list. FirstOrDefault returns null if no item is found, whereas First fails with "Sequence contains no elements" error.
var result = (from userChallenge in DataContext.UserChallenges
where userChallenge.ChallengeId == challengeId
select userChallenge).FirstOrDefault();
Related
I want to make a GL-Category Sequence like document sequence for every cash journal.
I added a field in cash journal window called journal number.
I want to generate a number for every cash journal and increment it by 1?
The document sequence is managed by the PO.java class in ADempiere. To use it, you need to add a column with the column name "DocumentNo" to your table. You will need to add the entry in the Sequence table to keep track of the numbers.
Here is the code from PO.java which is run when the record is first saved.
// Set new DocumentNo
String columnName = "DocumentNo";
int index = p_info.getColumnIndex(columnName);
if (index != -1 && p_info.getColumn(index).ColumnSQL == null)
{
String value = (String)get_Value(index);
if (value != null && value.startsWith("<") && value.endsWith(">"))
value = null;
if (value == null || value.length() == 0)
{
int dt = p_info.getColumnIndex("C_DocTypeTarget_ID");
if (dt == -1)
dt = p_info.getColumnIndex("C_DocType_ID");
if (dt != -1) // get based on Doc Type (might return null)
value = DB.getDocumentNo(get_ValueAsInt(dt), m_trxName, false, this);
if (value == null) // not overwritten by DocType and not manually entered
value = DB.getDocumentNo(getAD_Client_ID(), p_info.getTableName(), m_trxName, this);
set_ValueNoCheck(columnName, value);
}
}
I have this LINQ in C#, which I have to convert to a SQL query. And I am not sure how to do multiple filtering based on conditions:
var geofenceReport = companyContext.GeofenceSimpleReports.Where(x => x.EnterTime != null && x.ExitTime != null && x.MinutesInGeofence != null).AsQueryable();
if (model.GeofenceId != -1)
{
geofenceReport = geofenceReport.Where(x => x.iGeofenceId == model.GeofenceId).AsQueryable();
}
if (model.AssetId != -1)
{
geofenceReport = geofenceReport.Where(x => x.iAssetId == model.AssetId).AsQueryable();
}
if (model.CategoryId != -1)
{
geofenceReport = geofenceReport.Where(x => x.iCategoryId == model.CategoryId).AsQueryable();
}
if (model.SiteId != -1)
{
geofenceReport = geofenceReport.Where(x => x.iSiteId == model.SiteId).AsQueryable();
}
geofenceReport = geofenceReport
.Where(x => x.EnterTime >= model.StartDateTime &&
x.EnterTime <= model.EndDateTime)
.AsQueryable();
So this is what I came up with in SQL:
I created a new type for AssetId:
USE myDatabase
GO
CREATE TYPE idTable AS TABLE (id INT)
And then in SQL:
USE myDatabase
GO
CREATE PROCEDURE [dbo].[xPT_GetGeofenceSummaryReport]
#iAssetIds idTable,
#iGeofenceId INT,
#iCategoryId INT,
#iSiteId INT,
#iAssetId INT
AS
IF #iAssetId != -1
SELECT * FROM GeofenceSimpleReport WHERE iAssetId in (#iAssetIds)
IF #iGeofenceId != -1
SELECT * FROM GeofenceSimpleReport where iGeofenceId = #iGeofenceId
IF #iCategoryId != -1
SELECT * FROM GeofenceSimpleReport where iCategoryId = #iCategoryId
IF #iSiteId != -1
SELECT * FROM GeofenceSimpleReport where iSiteId = #iSiteId
and this GeofenceSimpleReport is a database view.
But this will not work as it is logically wrong. This will 4 separate selects from the GeofenceSimpleReport.
I need to have one read from GeofenceSimpleReport with all filters applied.
And I don't want to read this data temporarily into a TABLE/LIST in memory as there is a lot of data.
Is there a way to write this query dynamically like I am doing in LINQ?
You're thinking about this procedurally, and going through a series of if-statements, rather than approaching your view as a set of data that you can filter all at once.
You can filter on the original criteria related to EntryTime, ExitTime, etc., and then for each parameter for which you provide a filterable value (not -1) then make sure the Id matches that record in the table. Anything where you gave a -1 for the value will automatically make that AND statement true.
I do this sort of thing all the time by passing in nullable parameters - if they're non-NULL then I filter on them - otherwise they just evaluate to true and pass through.
USE myDatabase
GO
CREATE PROCEDURE [dbo].[xPT_GetGeofenceSummaryReport]
#iAssetIds idTable,
#iGeofenceId INT,
#iCategoryId INT,
#iSiteId INT,
#iAssetId INT
AS
SELECT *
FROM GeofenceSimpleReport
WHERE EnterTime IS NOT NULL
AND ExitTime IS NOT NULL
AND MinutesInGeofence IS NOT NULL
AND (#iAssetId = -1 OR iAssetId IN (#iAssetIds))
AND (#iGeofenceId = -1 OR iGeofenceId = #iGeofenceId)
AND (#iCategoryId = -1 OR iCategoryId = #ICategoryId)
AND (#iSiteId = -1 OR iSiteId = #iSiteId)
I am looking for a way to return the value of a precise column in the first result of a query.
The query result contains always 1 row containing the following columns :
ID
PW
RANK
I am trying to only get the rank value in order to push it into a session variable.
I tried messing with :
$row-> $query->row();
But then I don't know how to get only the value of the rank column. Ideally, I would want to get that value, then return it to allow my controller to set it in the session variable ( doing it in the model would be easier but would break the MVC pattern, right ?)
How can I do this ?
Thanks
Have the controller call a function in the model that return that value. Let's say the model has a function name get_rank()
public function get_rank($id)
{
// assumes your ID is an int
$id = (int)$id;
// avoid wasting a query
if ($id < 1) return FALSE;
// build query
$this->db->select('rank');
$this->db->from('YOUR_TABLE');
$this->db->where('id', $id);
// maybe some sorting / limiting here if you need it
// get result
$rs = $this->db->get();
if ($rs->num_rows() > 0)
{
// just get the first row
$row = $rs->row();
return $row->rank;
}
return FALSE;
}
I am re-writing a query which is created in response to user's entry into text fields in order to offer some protection against SQL injection attack.
SELECT DISTINCT (FileNameID) FROM SurNames WHERE Surname IN
('Jones','Smith','Armitage')
AND FileNameID IN ( SELECT DISTINCT (FileNameID) FROM FirstNames WHERE FirstName
IN ('John','William') )
There can be up to 3 other tables involved in this process.
The parameter lists can be up to 50-100 entries so building a parameterized query is tedious and cumbersome.
I am trying to create a Linq query which should take care of the parameterization and offer the protection I need.
This gives me what I need
var surnameValues = new[] { "Jones","Smith","Armitage" };
var firstnameValues = new[] { "John","William" };
var result = (from sn in db.Surnames
from fn in db.FirstNames
where surnameValues.Contains(sn.Surname) &&
firstnameValues.Contains(fn.FirstName)
select fn.FileNameID).Distinct().ToArray();
I now need a way to dynamically create this depending upon whether the user has selected/entered values in the surname or firstname text entry boxes?
Any pointers will be gratefully received
Thanks
Roger
you could combine all the logic into the query;
var surnameValues = new[] { "Jones","Smith","Armitage" };
var firstnameValues = null;
// Set these two variables to handle null values and use an empty array instead
var surnameCheck= surnameValues ?? new string[0];
var firstnameCheck= firstnameValus ?? new string[0];
var result = (from sn in db.Surnames
from fn in db.FirstNames
where
(!surnameCheck.Any() || surnameCheck.Contains(sn.Surname)) &&
(!firstnameCheck.Any() || firstnameCheck.Contains(fn.FirstName))
select fn.FileNameID).Distinct().ToArray();
Your query doesn't seem to have a join condition betwwen the Surnames table and the firstNames table?
You could dynamically build the query (as you appear to be doing I cross join I've used SelectMany)
var query=db.Surnames.SelectMany(sn=>db.FirstNames.Select (fn => new {fn=fn,sn=sn}));
if (surnameValues!=null && surnameValues.Any()) query=query.Where(x=>surnameValues.Contains(x.sn.Surname));
if (firstnameValues !=null && firstnameValues.Any()) query=query.Where(x=>firstnameValues.Contains(x.fn.FirstName));
var result=query.Select(x=>x.fn.FileNameID).Distinct();
I have this piece of code, that checks whether a returned object is null. If so, it will return 0, or else it will return a property inside the object.
var userPoints = (from Point p in entities.Point
where p.UserName == userName
select p).SingleOrDefault();
if (userPoints == null)
{
return 0;
}
else
{
return userPoints.Points;
}
Is it possible to simplify the if statements with the nullable operator? I've tried this, but the system throws an exception when attempting to read the property
return userPoints.Points ?? 0;
No, unfortunately there's nothing which will do exactly that. Options:
Use the conditional operator:
return userPoints == null ? 0 : userPoints.Points;
Change your query to make that do the defaulting:
return (from Point p in entities.Point
where p.UserName == userName
select p.Points).SingleOrDefault();
Personally I'd go for the latter approach :) If you wanted a default other than 0, you'd need something like:
return (from Point p in entities.Point
where p.UserName == userName
select (int?) p.Points).SingleOrDefault() ?? -1;
You can do this:
var userPoints = (from Point p in entities.Point
where p.UserName == userName
select p.Point).SingleOrDefault();
return userPoints;
If there are no results then userPoints will be 0, otherwise it will be the value of Points.
You can't use it in your context.
Explanation:
You want to check whether userPoints is null, but want to return userPoints.Points if it is not null.
The ?? operator checks the first operand for null and returns it, if it is not null. It doesn't work if what you want to check and what you want to return are two different things.
Hover over var with the mouse and see what type it is.