Entity Framework PredicateBuilder multiple "AND" && "OR" - sql

I need add And && Or same query
This is my code
var predicate = PredicateBuilder.True<Summon>();
if (!string.IsNullOrEmpty(param.id))
{
predicate = predicate.And(m => m.id== param.id);
}
if (!string.IsNullOrEmpty(param.subjects))
{
var subjectsPredicate = PredicateBuilder.False<Summon>();
string[] subjects = param.subjects.Split(',');
for (int i = 0; i < subjects.Length; i++)
{
subjectsPredicate = subjectsPredicate.Or(m => m.SubjectId ==subjects[i]);
}
predicate = predicate.And(subjectsPredicate);
}
My Problem is that when the subjects exist I got an error, all other queries work good just this "sub-query" make the query to fail.
This is my error, If subjects exist.

The solution is simple - Not using the array on the search query
subjects[i] - Does not work
instead of write
for (int i = 0; i < subjects.Length; i++)
{
subjectsPredicate = subjectsPredicate.Or(m => m.SubjectId ==subjects[i]);
}
Neet to write
foreach (string key in subjects)
{
subjectsPredicate = subjectsPredicate.Or(m => m.SubjectId == key);
}

Related

Delete CustomXml files -docx4j

How to delete custom XML files with its property and relationship files?, I've used clear() method. But it's not working. Help me out.
wordMLPackage.getCustomXmlDataStorageParts().clear();
https://github.com/plutext/docx4j/blob/master/docx4j-core/src/main/java/org/docx4j/Docx4J.java#L643 shows you how to do this. To remove them all, it would be:
protected static void removeDefinedCustomXmlParts(WordprocessingMLPackage wmlPackage) {
List<PartName> partsToRemove = new ArrayList<PartName>();
RelationshipsPart relationshipsPart = wmlPackage.getMainDocumentPart().getRelationshipsPart();
List<Relationship> relationshipsList = ((relationshipsPart != null) &&
(relationshipsPart.getRelationships() != null) ?
relationshipsPart.getRelationships().getRelationship() : null);
Part part = null;
if (relationshipsList != null) {
for (Relationship relationship : relationshipsList) {
if (Namespaces.CUSTOM_XML_DATA_STORAGE.equals(relationship.getType())) {
part = relationshipsPart.getPart(relationship);
partsToRemove.add(part.getPartName());
}
}
}
if (!partsToRemove.isEmpty()) {
for (int i=0; i<partsToRemove.size(); i++) {
relationshipsPart.removePart(partsToRemove.get(i));
}
}
}

realm react-native: how to query correctly an array of strings

can someone show me how to query an array of strings with realm in react-native?
assume i have an array like the following:
const preferences = ["automatic","suv","blue",eco]
What I want is to get realm results where ALL strings in the attribute "specifications" of Cars is in "preferences".
E.g.: If an instance of Cars.specifications contains ["automatic","suv"]
a result should be returned.
But if an instance of Cars.specifications contained ["automatic,"suv","green"] this instance shouldn't be returned.
The length of preferences can vary.
Thank you very much.
Update:
What i tried is the following:
const query = realm.objects("Cars").filtered('specifications = preferences[0] OR specifications = preferences[1]')
As you see it is an OR operator which is surely wrong and it is hardcoded. Looping with realm really confuses me.
This code will work!
const collection = realm.objects('Cars');
const preferences = ["automatic","suv","blue","eco"];
let queryString = 'ANY ';
for (let i = 0; i < preferences.length; i++) {
if (i === 0) {
queryString += `specifications CONTAINS '${preferences[i]}'`;
}
if (i !== 0 && i + 1 <= preferences.length) {
queryString += ` OR specifications CONTAINS '${preferences[i]}'`;
}
}
const matchedResult = collection.filtered(queryString);
example of function to test if a word is inside an array of word
function inArray(word, array) {
var lgth = array.length;
word = word.toLowerCase();
for (var i = 0; i < lgth; i++) {
array[i] = (array[i]).toLowerCase();
if (array[i] == word) return true;
}
return false;
}
const preferences = ["automatic","suv","blue","eco"];
const specifications = ["automatic","suv"] ;
const specifications2 = ["automatic","suv", "boat"] ;
function test(spec,pref){
for (var i in spec){
if(!inArray(spec[i],pref)){
return false ;
}
}
return true;
}
console.log(test(specifications,preferences));
console.log(test(specifications2,preferences));
https://jsfiddle.net/y1dz2gvu/

working with option of $query in yii2

i want use where for $query.
foreach ($oppId as $o) {
$id = $o['opportunity_id'];
$query->Where("id=$id");
}
When I use this. All items shown
$query->orWhere("id=$id");
i need get this query :
SELECT * FROM `opportunity` WHERE id =27 or id =28
this is all of my function :
public function actionShow($type = 0, $city = 0, $client = 0) {
$query = (new \yii\db\Query())->select(['*'])->from('opportunity ')->innerJoin('profile_details', 'opportunity.user_id=profile_details.user_id')->orderBy('id desc');
$query->Where('id !=-1');
if (isset($_REQUEST['type'])) {
$type = $_REQUEST['type'];
if ($type != 0) {
$query->andWhere("project_type_id=$type");
}
}
if (isset($_REQUEST['city'])) {
$city = $_REQUEST['city'];
if ($city != 0) {
$query->andWhere("state_id=$city");
}
}
if (isset($_REQUEST['client'])) {
$client = $_REQUEST['client'];
if ($client != 0) {
$oppId = \app\models\OpportunityControl::find()
->where('project_type_id = :project_type_id', [':project_type_id' => $client])
->all();
foreach ($oppId as $o) {
$id = $o['opportunity_id'];
$query->orWhere("id=$id");
}
}
}
You very much do not want to use strings to add to the query under any circumstances as that is ripe for SQL injection. I'd format it like this:
...
$params = [];
foreach ($oppId as $o) {
$params[] = $o->opportunity_id;
}
$query->andWhere(['in', 'id', $params]);
...
You should also adjust your other query params so that you are not passing variables into SQL via a string.
if (isset($_REQUEST['type'])) {
$type = $_REQUEST['type'];
if ($type != 0) {
$query->andWhere(['project_type_id' => $type]);
}
}
if (isset($_REQUEST['city'])) {
$city = $_REQUEST['city'];
if ($city != 0) {
$query->andWhere(['state_id' => $city]);
}
}
See the Yii2 guide on using variables in queries for what you are trying to avoid here. Specifically:
Do NOT embed variables directly in the condition like the following, especially if the variable values come from end user inputs, because this will make your application subject to SQL injection attacks.
// Dangerous! Do NOT do this unless you are very certain $status must be an integer.
$query->where("status=$status");
I do it with Arrays
$query->where(['or',['id'=>27],['id'=>28]]);
But in your case save all ids in a Array is not possible,I do it with string inside foreach
$StringWhere='';
$LastElement = end($oppId);
foreach ($oppId as $o)
{
$id = $o['opportunity_id'];
$StringWhere.=' id='.$id;
if($o!=$LastElement)
{
$StringWhere.=' or ';
}
}
$query->where($StringWhere);
$query->where(['or',['id'=>27],['id'=>28]]);
I use this and it works perfectly as mentioned by metola. :)

How to build NHibernate Or criteria from two foreach?

In my project I try to buid criteria like this:
ICriteria criteria = session.CreateCriteria(typeof(Orders), typeof(Orders).Name);
if (param != null)
{
if (param[1] != "System")
{
for (int index = 0; index < param.Length - 1; index++)
{
if (!string.IsNullOrEmpty(param[index]))
{
criteria.Add(Expression.Eq(
"RealizationPoint",
CommonUtils.GetNameRealizationPointById(param[index])));
}
}
}
if (param[1] != "System" && param2 != null &&
!string.IsNullOrEmpty(param2[0]))
{
for (int index = 0; index < param2.Length - 1; index++)
{
if (!string.IsNullOrEmpty(param2[index]))
{
criteria.Add(Expression.Eq(
"RealizationPoint",
CommonUtils.GetNameRealizationPointById(param2[index])));
}
}
}
}
para1, param2: string[] param1, string[] param2.
In result between expression stay AND, I need OR.
You could use Restrictions.Disjunction() to group multiple expressions as OR and Restrictions.Conjuctions() as AND.
Simplified example:
var conjunction1 = Restrictions.Conjunction();
for (int index = 0; index < param.Length -1; index++)
{
conjunction1.Add(Restrictions.Eq("RealizationPoint", param[index]));
}
var conjunction2 = Restrictions.Conjunction();
for (int index = 0; index < param2.Length -1; index++)
{
conjunction2.Add(Restrictions.Eq("RealizationPoint", param2[index]));
}
criteria.Add(Restrictions.Disjunction().Add(conjunction1).Add(conjunction2));
// Or with Restrictions.Or()
// criteria.Add(Restrictions.Or(conjunction1, conjunction2));
You can find more info and alternatives in this SO question: How to create OR statements for NHibernate?

How can I do this all in one query? Nhibernate

I have a list of Ids and I want to get all the rows back in one query. As a list of objects(So a List of Products or whatever).
I tried
public List<TableA> MyMethod(List<string> keys)
{
var query = "SELECT * FROM TableA WHERE Keys IN (:keys)";
var a = session.CreateQuery(query).SetParameter("keys", keys).List();
return a; // a is a IList but not of TableA. So what do I do now?
}
but I can't figure out how to return it as a list of objects. Is this the right way?
List<TableA> result = session.CreateQuery(query)
.SetParameterList("keys", keys)
.List<TableA>();
Howeever there could be a limitation in this query if number of ":keys" exceed more than 1000 (incase of oracle not sure with other dbs) so i would recommend to use ICriteria instead of CreateQuery- native sqls.
Do something like this,
[TestFixture]
public class ThousandIdsNHibernateQuery
{
[Test]
public void TestThousandIdsNHibernateQuery()
{
//Keys contains 1000 ids not included here.
var keys = new List<decimal>();
using (ISession session = new Session())
{
var tableCirt = session.CreateCriteria(typeof(TableA));
if (keys.Count > 1000)
{
var listsList = new List<List<decimal>>();
//Get first 1000.
var first1000List = keys.GetRange(0, 1000);
//Split next keys into 1000 chuncks.
for (int i = 1000; i < keys.Count; i++)
{
if ((i + 1)%1000 == 0)
{
var newList = new List<decimal>();
newList.AddRange(keys.GetRange(i - 999, 1000));
listsList.Add(newList);
}
}
ICriterion firstExp = Expression.In("Key", first1000List);
ICriterion postExp = null;
foreach (var list in listsList)
{
postExp = Expression.In("Key", list);
tableCirt.Add(Expression.Or(firstExp, postExp));
firstExp = postExp;
}
tableCirt.Add(postExp);
}
else
{
tableCirt.Add(Expression.In("key", keys));
}
var results = tableCirt.List<TableA>();
}
}
}