how to write "select * from PUB_PAGE_MENUSTRUCTUR where PARENTID is null" using lambda - sql

This is my lambda to get the data from pub_page_menustructur
DataHelper.DataObj.QueryTable(SystemType.H0, p=>p.PARENTID == null) this is the lambda expression i had write. it have the same effection as "select * from pub_page_menustructur where parentid = null" show in the picture. is there any other way to show as "parentid is null"

This way work for you if you are using Entity Framework
var result = dbcontext.PUB_PAGE_MANUSTRUCTURE.Where(w => w.PARENTID == null).ToList();

the answer is
var result = dbcontext.PUB_PAGE_MANUSTRUCTURE.Where(w => w.PARENTID.Trim() == null).ToList();

Related

Can Laravel automatically switch between column = ? and column IS NULL depending on value?

When building a complex SQL query for Laravel, using ? as placeholders for parameters is great. However when the value is null, the SQL syntax needs to be changed from = ? to IS NULL. Plus, since the number of parameters is one less, I need to pass a different array.
To get it to work, I have written it like this, but there must be a better way:
if ($cohortId === null) {
// sql should be: column IS NULL
$sqlCohortString = "IS NULL";
$params = [
Carbon::today()->subDays(90),
// no cohort id here
];
} else {
// sql should be: column = ?
$sqlCohortString = "= ?";
$params = [
Carbon::today()->subDays(90),
$cohortId
];
}
$query = "SELECT items.`name`,
snapshots.`value`,
snapshots.`taken_at`,
FROM snapshots
INNER JOIN (
SELECT MAX(id) AS id, item_id
FROM snapshots
WHERE `taken_at` > ?
AND snapshots.`cohort_id` $sqlCohortString
GROUP BY item_id
) latest
ON latest.`id` = snapshots.`id`
INNER JOIN items
ON items.`id` = snapshots.`item_id`
ORDER by media_items.`slug` ASC
";
$chartData = DB::select($query, $params);
My question is: does Laravel have a way to detect null values and replace ? more intelligently?
PS: The SQL is for a chart, so I need the single highest snapshot value for each item.
You can use ->when to create a conditional where clause:
$data = DB::table('table')
->when($cohortId === null, function ($query) {
return $query->whereNull('cohort_id');
}, function ($query) use ($cohortId) {
// the "use" keyword provides access to "outer" variables
return $query->where('cohort_id', '=', $cohortId);
})
->where('taken_at', '>', $someDate)
->toSql();

Convert SQL to LINQ/EF

I want to convert this SQL query to LINQ. But I'm new in EF. Please help
SQL Query
select * from VersionHistory where id in( select OptionsId from StylesHistory where ConId=540 and OptionsId = 28286 and ModifiedAtVersion>1)
TIA
I tried Something like this
var stylesHistory = _context.VersionHistory
.Where(x => x.ModifiedAtVersion > 1
&& x.Id==28286
&& x.Contract.Id==540)
.ToList()
Not Sure How I can add Sub Query
You can easily write that as:
var result = ctx.VersionHistory
.Where(vh => ctx.StylesHistory
.Any( sh => sh.OptionsId == vh.Id &&
sh.OptionsId == 28286 &&
sh.ConId = 540 &&
sh.ModifiedAtVersion > 1));
You can also create your subquery as another IEnumerable which you'll use in the main query.
This will improve readibility.
EF will only generate one query.

Entity Framework if statement inside select

I have a problem in generating an Entity Framework query and not okay with linq style one :.....
This is my attempt:
var query = db.table
.Where(x => x.colA == 1)
.GroupBy(x => new {x.min,x.max})
.Select(y => if(y.key.min==0 && y.key.max==0)
{ " unchanged " }
else
{ y.key.min.tostring()+" "+y.key.max.tostring() })
.ToList()
I want to get "unchanged" string, if both value ofmin and max are zero, otherwise concat them
Use the conditional operator
// ...
.Select(y=> y.key.min==0 && y.key.max==0
? " unchanged "
: y.key.min.tostring()+" "+y.key.max.tostring())
// ...
Apparently all elements in your table have properties min and max
After GroupBy(x=> new {x.min,x.max}) you'll have a sequence of groups, where each group has a key {min, max}, all elements in the group have this value for their min and max properties.
After the GroupBy, you take every group, and from every group you'll select exactly one string. You get rid of the element of the group.
The string that you select depends on the key of the group: if the key = {0, 0} you select the string "unchanged", else you select the string:
y.key.min.tostring()+" "+y.key.max.tostring()
The result is a list of strings, something like:
"3 7",
"4 10,
"unchanged",
"2 8",
Are you sure you want this?
In that case you won't need the GroupBy. Distinct will be simpler and faster
List<string> result = db.table
.Where(tableRow => tableRow.colA == 1)
.Select(tableRow => tableRow.min==0 && tableRow.max==0
? " unchanged "
: tableRow.min.tostring()+" "+tableRow.max.tostring())
// from here you have a sequence of strings
// get rid of duplicates:
.Distinct()
.ToList();
For this specific case, you can use Conditional Operator (?:)
var query = db.table
.Where(x=> x.colA == 1)
.GroupBy(x=> new {x.min,x.max})
.Select(y=> (y.Key.min == 0 && y.Key.max == 0) ? " unchanged" : (y.Key.min.ToString()+" "+y.Key.max.ToString()))
.ToList();
Sorry I can't try it right now, but i think this should work
var query = db.table
.Where(x=> x.colA == 1)
.GroupBy(x=> new {x.min,x.max})
.Select(y=> {if(y.key.min==0 && y.key.max==0)
{
" unchanged "
} else
{
y.key.min.tostring()+" "+y.key.max.tostring();
} return y;})
.ToList()

Why does RavenDB perform an OR operation instead of an AND?

Why is there a OR instead of an AND between the SEARCH and the WHERE?
The problem is that the current Lucene query is:
"OrganizationType:Boo ( Name:(Foo) ShortName:(Foo))"
instead of:
"OrganizationType:Boo AND ( Name:(Foo) ShortName:(Foo))"
How can I change that?
RavenQueryStatistics stats;
var organizationQuery = session.Query<Organization>()
.Statistics(out stats)
.Skip((request.Page - 1) * request.PageSize)
.Take(request.PageSize);
if (request.OrganizationType != default(OrganizationType))
{
organizationQuery = organizationQuery.Where(o => o.OrganizationType == request.OrganizationType);
}
if (!string.IsNullOrEmpty(request.Query))
{
organizationQuery = organizationQuery
.Search(c => c.Name, request.Query, escapeQueryOptions: EscapeQueryOptions.AllowPostfixWildcard)
.Search(c => c.ShortName, request.Query, escapeQueryOptions: EscapeQueryOptions.AllowPostfixWildcard);
}
I have added a screenshot with the proposed solution:
To get only documents matching all sub-queries you to have to use Intersect. See the article How to use intersect in the RavenDB documentation.
Because Search is using OR by default. There is an optional parameter that set it to use AND.

Avoid repeating an expression in a LINQ to Entities query

I have the following query:
val = val.Select(item => new SimpleBill { CTime = item.CTime, Description = item.Description, ID = item.ID,
IDAccount = item.IDAccount, OrderNumber = item.OrderNumber, PSM = item.PSM, Sum = item.Sum,
Type = (BillType)item.Type,
ByteStatus = ((Bill)item).Payments.OrderByDescending(payment => payment.ID).FirstOrDefault().Status,
LastPaymentDate = ((Bill)item).Payments.OrderByDescending(payment => payment.ID).FirstOrDefault().CTime,
LastPaymentSum = ((Bill)item).Payments.OrderByDescending(payment => payment.ID).FirstOrDefault().Sum });
}
Is it possible to avoid repeating the ((Bill)item).Payments.OrderByDescending(payment => payment.ID).FirstOrDefault() part 3 times? I tried turning it into a method and into a delegate - the code compiled in both cases, but produced an exception at runtime.
You can use the let contstruct as follows:
val = from item in val
let lastPayment = ((Bill)item).Payments
.OrderByDescending(payment => payment.ID)
.FirstOrDefault()
select new SimpleBill
{
lastPayment.CTime,
//Rest of fields
}
However, as you may noticed this uses the LINQ Query syntax vs. Method syntax. IIRC let is only available in the former.