Subsonic Delete multiple records - subsonic

I have a table which has a two fields, userid and degreeid. A user can have multiple degreeds in this table. When a user select their degree I want to delete any degree id already in the database but un-selected by user. How should do it? I try to use something like this with no luck.
repo.DeleteMany(x=>x.MeetingAttendeeUserID==userID && x.EducationDegreeID userDegreeList)
Thanks,
Lewis

Could you do something like this?
repo.DeleteMany(x =>
x.MeetingAttendeeUserId == userID &&
x.EducationDegreeID != selectedDegreeId
);
Edit: Or this.
repo.DeleteMany(x =>
x.MeetingAttendeeUserId == userID &&
userDegreeList.Contains(x.EducationDegreeID))
);

I have tried
SubSonicRepository<ReportDatum> repo = new SubSonicRepository<ReportDatum>(db);
repo.DeleteMany(x => x.ReportID == Convert.ToInt32(reportID));
and it does nothing, not even an error.
Addendum for someone that comes across this:
don't convert in the delete call, convert your variables beforehand.
int deleteKey = Convert.ToInt32(reportID)
SubSonicRepository<ReportDatum> repo = new SubSonicRepository<ReportDatum>(db);
repo.DeleteMany(x => x.ReportID == deleteKey);
and it fired fine.

I would recommend if you dont know Lamda expression. Create your own stored procedure and call use it.
This will not restrict you using lamda expression if you don't have time to learn it.
Ultimately you wanted to done your job.

Related

Is there a way to add an incrementing id in one statement in MongoDB?

So I got a small database, It's not going to grow much more and I'm trying to get one document from the db in an API that I implemented in python so that with a given document Id I retrieve the document in the db. However, I find it a little hard to put the user to write a random number from the db. All I require is a function that modifies each document by setting an id field and to Auto-Increment. As I said, it's not going to grow that much and the performance isn't really an issue here.
So far what I've been able to do is this:
var i = 0
db.MyCollection.update({},
{$set : {"new_field":1}},
{upsert:false,
multi:true}
i ++;),
I achieved to set an id field but it sets the same number to each document (the count of every document) So let's say that if the db has 10 docs, it'll set the Id to 10.
Find-and-modify operation returns the document updated (before or after the update depending on returnDocument setting). You can use this with $inc to implement a counter. Ruby example where c is a collection:
irb(main):005:0> c['foo'].insert_one(counter:true,count:1)
=> #<Mongo::Operation::Insert::Result:0x8040 documents=[{"n"=>1, "opTime"=>{"ts"=>#<BSON::Timestamp:0x00005609f260b7e0 #seconds=1594961771, #increment=2>, "t"=>1}, "electionId"=>BSON::ObjectId('7fffffff0000000000000001'), "ok"=>1.0, "$clusterTime"=>{"clusterTime"=>#<BSON::Timestamp:0x00005609f260b538 #seconds=1594961771, #increment=2>, "signature"=>{"hash"=><BSON::Binary:0x8060 type=generic data=0x0000000000000000...>, "keyId"=>0}}, "operationTime"=>#<BSON::Timestamp:0x00005609f260b290 #seconds=1594961771, #increment=2>}]>
irb(main):011:0> c['foo'].find_one_and_update({counter:true},{'$inc':{count:1}})
=> {"_id"=>BSON::ObjectId('5f112f6b2c97a6281f63f575'), "counter"=>true, "count"=>1}
irb(main):012:0> c['foo'].find_one_and_update({counter:true},{'$inc':{count:1}})
=> {"_id"=>BSON::ObjectId('5f112f6b2c97a6281f63f575'), "counter"=>true, "count"=>2}
irb(main):013:0> c['foo'].find_one_and_update({counter:true},{'$inc':{count:1}})
=> {"_id"=>BSON::ObjectId('5f112f6b2c97a6281f63f575'), "counter"=>true, "count"=>3}
irb(main):014:0> c['foo'].find_one_and_update({counter:true},{'$inc':{count:1}})
=> {"_id"=>BSON::ObjectId('5f112f6b2c97a6281f63f575'), "counter"=>true, "count"=>4}
Why not just use this logic? Instead of updating all via one query, just launch multiple queries one by one? Mongo will do it pretty fast, even if you have >1M docs in database (according to your phrase: I got a small database) because pre-builded index on _id field.
this is a javasript code, but I guess, you'll understand the logic of it
let all_documents = db.MyCollection.find({});
for (let i = 0; i < all_documents.length; i++) {
db.MyCollection.update({_id: all_documents[i]._id }, {$set : {"new_field": i}}, {upsert:false})
}

NotesXSPDocument and NotesDocument

I have created a function in SSJS Library. Because I use it in more than one XPages.
When I call this function behind a button I cannot see the value in the field
If I print it out I can see the value at the Admin Console but cannot see it in the form Even if I get page with full refreshed.
Actually my another question is.. is it possible to compare notesXSPDocument and NotesDocument. Maybe someoen can say that what is the best way for that?
function deneme(document1:NotesXSPDocument,otherDocfromOtherDatabase:NotesDocument)
{
//do staff here
if (document1.getItemValueString("field1")==otherDocfromOtherDatabase.getItemValueString("field2"))
{ //do some staff here...
document1.replaceItemValue("fieldName","FieldValue");}
}
You can compare item values from Document and XSPDocument, just be careful with the type you are comparing.
In your code you are comparing 2 javascript strings with == operator.
The code seems to be OK, just remember to save the document1 after the changes and maybe check that the items have some value.
var valueFromXspDoc = document1.getItemValueString("field1");
var valueFromDoc = otherDocfromOtherDatabase.getItemValueString("field2");
if (valueFromXspDoc && valueFromDoc && (valueFromXspDoc === valueFromDoc)) {
// stuff here...
document1.replaceItemValue("fieldName","FieldValue");
document1.save();
}
Don not compare it with == sign. A better way is to document1.getItemValueString("field1").equals(otherDocfromOtherDatabase.getItemValueString("field2"))

Filter resources by template variable value with MODx Wayfinder

I have a site that uses Wayfinder to display the latest 3 entries from an Articles blog. Now, I want to only consider those blog entries that are tagged Highlights.
My original Wayfinder call looks like this, nothing spectacular:
[[!Wayfinder? &startId=`296` &level=`1`
&outerTpl=`emptyTpl`
&innerTpl=``
&rowTpl=`thumbnails_formatter`
&ignoreHidden=`1`
&sortBy=`menuindex`
&sortOrder=`DESC`
&limit=`3`
&cacheResults=`0`
]]
as Articles tags are managed via the articlestags TV, I thought that a &where might do the trick, but with no luck yet:
&where=`[{"articlestags:LIKE":"%Highlights%"}]`
does not yield anything. As a sanity check, I tried [{"pagetitle:LIKE":"%something%"}], which worked. Obviously, the problem is that articlestags is not a column of modx_site_content, but I'm not sure about how to put the subquery.
SELECT contentid
FROM modx_site_tmplvar_contentvalues
WHERE tmplvarid=17
AND value LIKE '%Highlights%'
Gave me the right IDs on the sql prompt, but adding it to the Wayfinder call like this gave an empty result again:
&where=`["id IN (SELECT contentid FROM modx_site_tmplvar_contentvalues WHERE tmplvarid=17 AND value LIKE '%Highlights%')"]`
Any ideas on how to achieve this? I'd like to stay with Wayfinder for consistency, but other solutions are welcome as well.
You can just use pdomenu (part of pdoTools) instead Wayfinder
[[!PdoMenu?
&startId=`296`
&level=`1`
&outerTpl=`emptyTpl`
&innerTpl=``
&rowTpl=`thumbnails_formatter`
&ignoreHidden=`1`
&sortBy=`menuindex`
&sortOrder=`DESC`
&limit=`3`
&cacheResults=`0`
&includeTVs=`articlestags`
&where=`[{"TVarticlestags.value:LIKE":"%filter%"}]`
]]
Take a peek at some of the config files [core/components/wayfinder/configs ] - I have not tried it, but it looks as if you can run your select query right in the config & pass the tmplvarid array to the $where variable.
A little playing around led me to a solution: I needed to include the class name (not table name) when referring to the ID:
&where=`["modResource.id IN (SELECT contentid FROM modx_site_tmplvar_contentvalues WHERE tmplvarid=17 AND value LIKE '%Highlights%')"]`
a small test showed that even a simple
&where=`["id = 123"]`
does not work without modResource..
A look at wayfinder.class.php shows the following line, which seems to be the "culprit":
$c->select($this->modx->getSelectColumns('modResource','modResource'));
This method aliases the selected columns - relevant code is in xpdoobject.class.php. The first parameter is the class name, the second a table alias. The effect is that the query selects id AS modResource.id, and so on.
EDIT: final version of my query:
&where=`["modResource.id IN (
SELECT val.contentid
FROM modx_site_tmplvars AS tv
JOIN modx_site_tmplvar_contentvalues AS val
ON tv.id = val.tmplvarid
WHERE tv.name = 'articlestags' AND (
val.value = 'Highlights'
OR val.value LIKE 'Highlights,%'
OR val.value LIKE '%,Highlights'
OR val.value LIKE '%,Highlights,%'
)
)"]`
I don't claim this query is particularly efficient (I seem to recall that OR conditions are bad). Also, MODx won't work with this one if the newlines aren't stripped out. Still, I prefer to publish the query in its well-formatted form.
I used snippet as a parameter for the includeDocs of wayfinder, In my case it was useful because I was need different resources in menu depend on user browser (mobile or desktop)
[[!Wayfinder?
&startId=`4`
&level=`1`
&includeDocs=`[[!menu_docs?&startId=`4`]]`
&outerTpl=`home_menu_outer`
&rowTpl=`menu_row`
]]
and then menu_docs snippet
<?php
if (empty ($startId))
return;
if (!isMobileDevice())
return;
$query = $modx->newQuery('modResource');
$query->innerJoin('modTemplateVarResource','TemplateVarResources');
$query->where(array(
'TemplateVarResources.tmplvarid' => 3,
'TemplateVarResources.value:LIKE' => 'yes',
'modResource.parent' => $startId,
'modResource.deleted' => 0,
'modResource.published' => 1,
'modResource.hidemenu' => 0
));
$resources = $modx->getCollection('modResource', $query);
$ouput = array();
foreach ($resources as $resource)
$output[] = $resource->get('id');
return implode (',', $output);

CouchDB: representing NVL() in view

I'm writing a Couchdb _design document for the SQL command below:
SELECT NVL(MAX(NVL(VERSION,0)),0)+1 FROM pricelistdocs WHERE
PRICE_LIST_ID = ? AND DELETION_FLAG = 0;
I came up with a _design view function below while run and return values but I doubt if the correct and fulfills expectation of the above SQL command.
function(doc){
if(doc.PRICE_LIST_ID == "110011" && doc.DELETION_FLAG == "0" ){
emit(doc._id, doc.VERSION);
}
}
Please how can I add the NVL() and MAX function to my _design view document above.
Any infortiom or clue is appreciated. Thank you for your time.
You can write your own NVL function by checking for the existance of a field and returning 0 if it does not exist.
For the max functionality, you have to add a reduce function to your view. If you just want to get the maximum, "reduce": "_max" will do, which is a built in reduce function.

Complex queries in linq to nhibernate

We are using accountability pattern for organizational structure. I using linq to nhibernate to find some departments and position but I have two problem.
var query =
Repository<Party>.Find(p => p.IsInternal == true)
.Where(p => p.Parents.Any(c => c.Parent.PartyId == id))
.Where(p =>
(
p.PartyType.PartyTypeId == (int)PartyTypeDbId.Department &&
_secretariat.Departments.Select(c => c.PartyId).Contains(p.PartyId)
)
||
(
p.PartyType.PartyTypeId == (int)PartyTypeDbId.Position &&
p.Children.Any(c =>
c.AccountabilityType.AccountabilityTypeId == (int)AccountabilityTypeDbId.TenurePersonOfPosition &&
((Person)c.Child).UserName != null)
)
);
First : I got 'Unhandled Expression Type: 1003' for this part of query : '_secretariat.Departments.Select(c => c.PartyId).Contains(p.PartyId)'
and I got Property not found 'UserName'
We have many complex queries i think we need to use stored procedure.
Sorry for bad Inglish!
One nice thing that you can do with LINQ is break your queries into multiple parts. Since you are building an expression tree that won't get executed until the results are enumerated, you don't have to do it all in one line (like SQL).
You can even make some reusable "filters" that you can apply to IQueryable. These filter functions accept an IQueryable as an argument, and return one as a result. You can build these as extension methods if you like (I like to).
As for your immediate problem, you may want to try a join on _secretariat instead of attempting a subquery. I've seen them work in scenarios where subqueries don't.
In addition to Lance's comments you might want to look at a compiled Linq query and breaking up some of the responsibilties to follow SOLID principles.
I've just also found out that there are issues with the Contains when containing Any linq methods. However, Any seems to work well within Any, hence:
_secretariat.Departments.Select(c => c.PartyId).Any(x => x == p.PartyId)

Resources