Filtering in Linq in MVC4 - linq

My table structure is as follows
Course
ID CourseName
1 PHP
2 WORDPRESS
MainCourse
ID MainCourseName
1 FoundationPhp
2 FoundationWordPress
3 Diploma
SubCourse
ID MainCourseID CourseID
1 1 1
2 2 2
3 3 1
3 3 2
I have a search scenario which should fetch the below result
When an user searches by PHP alone,he should get the following result
MainCourseName CourseCombination
FoundationPHP PHP
Diploma PHP,WORDPRESS
When an user searches by WORDPRESS alone,he should get the following result
MainCourseName CourseCombination
FoundationWordPress WORDPRESS
Diploma PHP,WORDPRESS
When an user searches by PHP,WORDPRESS ,he should get the following result.
MainCourseName CourseCombination
Diploma PHP,WORDPRESS
NOTE:If there is any other combination that contains both PHP & WORDPRESS that should be shown as well.Example of one such combination will be like PHP,WORDPRESS,JAVA.
I have tried the following method
List<int> CourseId={1,2}//means user searches by both PHP & WORDPRESS
var courseList = _db.SubCourses
.AsEnumerable()
.Where(mcd => courseId.Contains(mcd.Course.Id))
.Select(mc => new RegistraionVM.clsCourseCodeSearch
{
CourseCode = mc.MainCourse.MainCourseName,
CourseCombination = string.Join(",", mc.MainCourse.SubCourse
.Select(mcd => mcd.Course.Name))
}).Distinct().Take(5).ToList();
The above query returns the following result
MainCourseName CourseCombination
FoundationPHP PHP
FoundationWordPress WORDPRESS
Diploma PHP,WORDPRESS
Desired result is
MainCourseName CourseCombination
Diploma PHP,WORDPRESS
How can I acheive the above result

You need to first groupby the MainCourseID, then use an .All() clause to select only items where all the resulting subcourses are included in the filter
var filter = new int[] { 1 }; // or new int[] { 1, 2 } etc
var results = list.GroupBy(x => x.MainCourseID).Select(x => new
{
MainCourse = x.FirstOrDefault().MainCourse,
SubCourseIDs = x.Select(y => y.Course.ID),
SubCourseNames = x.Select(y => y.Course.CourseName)
}).Where(x => filter.All(y => x.SubCourseIDs.Contains(y))).Select(x => new RegistraionVM.clsCourseCodeSearch()
{
CourseCode = x.MainCourse.MainCourseName,
CourseCombination = String.Join(", ", x.SubCourseNames)
}).Take(5).ToList();

PHP = 1
And MainCourse 1 and 3 have Course PHP = 1
so it should say:
FoundationPhp PHP
Diploma PHP,WORDPRESS
Or else I dont understand your question.

Related

Linq with join - Get single result

I'm stucked with a linq query and I need a little bit of help.
I have the following tables
Table: Client
ClientId Name Age
(integer)
-------- ---------- -----
12635 John 23
87263 Derek 43
65237 Sarah 36
84735 Alice 28
Table: Action
Id Action ObjecId
(varchar)
-------- --------- ---------
202 Firefox 87263
203 Chrome 65237
204 Android 87263
205 Explorer 84735
206 Firefox 12635
My goal is to join both tables using ClientId and ObjectId fields. And for the Action table for each user I need to get only one record. If user has two records I need to get only the one with value='Android'
So the result with the above data should be:
Derek Android
Sarah Chrome
Alicie Explorer
John Firefox
I'm using the following approach.
var query = Set as IQueryable<Client>;
var actionQuery = Set as IQueryable<Action>
query= query.Join(actionQuery,
Client=> Client.ClientId.ToString(),
Action => Action.ObjectId.ToString(),
(Client, Action) => Client);
With the above I have a duplicate record for Derek, I need to get only one record for him, but I don't know how to do it. If a user has 2 records I need to get only the one with value='Android'.
Please, can you help me?
Thanks
If you need only a record where the ActionId is the highest, I'd do the following:
query = query.Join(actionQuery,
Client=> Client.ClientId.ToString(),
Action => Action.ObjectId.ToString(),
(Client, Action) => new { Client = Client, Action = Action })
.GroupBy(g => g.Client.Id)
.Select(g => g.OrderByDescending(gr => gr.Action.Id).First());
EDIT:
After the OP specified that if there are more actions for a particular client, one of those is always "Android" and this one must be chosen, I'm providing the following query:
query = query.Join(actions,
Client => Client.Id.ToString(),
Action => Action.ObjectId.ToString(),
(Client, Action) => new { Client = Client, Action = Action })
.GroupBy(g => g.Client.Id)
.Select(g => (g.Count() > 1) ? g.Where(gr => "Android".Equals(gr.Action.ActionDesc)).First() : g.First());

how to exchange data in laravel

I have the table structure below
how so that, if processed with the button, id_modul can change
id id_level id_modul
1 1 1
2 1 3
3 1 2
please, help me!
You can do something like this:
$module = Module::where('id_level', 1)->where('id_module', 3)->get();
$module->update(['id_module' => 1]);
like this
$foo_2 = Foo::where('id_modul', 2)->get();
$foo_3 = Foo::where('id_modul', 3)->get();
foreach ($foo_2 as $foo) {
$foo->id_modul = 3;
$foo->save();
}
foreach ($foo_3 as $foo) {
$foo->id_modul = 2;
$foo->save();
}

how to sum column value using group by collection in magento(USING MAGENTO STANDARD)

my table is like this and my collection is
$testmodel=Mage::getModel(test/p1)->getCollection();
my database table is below.
id cat_id rate p_id
1 1 4 1
2 1 2 1
3 1 3 2
4 2 5 3
5 2 3 1
and i want output like this in magento using collection
cat_id rate count_category
1 9 3
2 8 2
i found my PROBLEM correct code is below
$testmodel = Mage::getModel('test/p1')
->getCollection()
->addFieldToSelect('rate')
->addFieldToSelect('cat_id');
$testmodel ->getSelect()
->columns('SUM(rate) as total,COUNT(*) AS countCategory')
->group('cat_id');
if you use mysql4 as this model resource class then go to
Model/Mysql4/P1/Collection.php
here you need to add function
public function addGroupByCatId(){
$subSelect = clone $this->getSelect();
$CountsubSelect = clone $this->getSelect();
$subSelect->reset()
->from(array('rev' => 'youtable', 'SUM( rev.rate)')
->where('main_table.cat_id = rev.cat_id');
$CountsubSelect->reset()
->from(array('countrev' => 'youtable'),'COUNT(countrev.cat_id)')
->where('main_table.cat_id = countrev.cat_id');
$this->getSelect()
->join(
array('r' => 'youtable'),
'main_table.id = r.id',
array(
'review_sum' => new Zend_Db_Expr(sprintf('(%s)', $subSelect)),
'count_category' => new Zend_Db_Expr(sprintf('(%s)', $CountsubSelect)),
))
->group('main_table.cat_id');
return $this;
}
OR: Resouce as resource model then goto
if you use mysql4 as this model resource class then go to
Model/Resource/P1/Collection.php
here you need to add function
public function addGroupByCatId(){
$subSelect = clone $this->getSelect();
$CountsubSelect = clone $this->getSelect();
$subSelect->reset()
->from(array('rev' => 'youtable', 'SUM( rev.rate)')
->where('main_table.cat_id = rev.cat_id');
$CountsubSelect->reset()
->from(array('countrev' => 'youtable'),'COUNT(countrev.cat_id)')
->where('main_table.cat_id = countrev.cat_id');
$this->getSelect()
->join(
array('r' => 'youtable'),
'main_table.id = r.id',
array(
'review_sum' => new Zend_Db_Expr(sprintf('(%s)', $subSelect)),
'count_category' => new Zend_Db_Expr(sprintf('(%s)', $CountsubSelect)),
))
->group('main_table.cat_id');
return $this;
}
and final you get
$testmodel=Mage::getModel(test/p1)->getCollection();
$testmodel->addGroupByCatId();

How can I do this update query in ruby with sinatra?

I have table blogs and I want to add one to column views when user enter to the blog page .
DB[:blogs].where(:id => params[:id]).update(:views => :views + 1)
but it gave me error when I enter to the blog page in +
undefined method `+' for :views:Symbol
I'm do this :
blog = DB[:blogs].where(:id => params[:id]).first
views = blog[:views] + 1
DB[:blogs].where(:id => params[:id]).update(:views => views)
but this is add 3 or 5 or 1 or 4 not 1 only
(The question has nothing about Sinatra, just Sequel, which is not a part of Sinatra, but rather standalone library.)
You can do this:
DB[:blogs].where(:id => params[:id]).
update(Sequel.expr(:views) => Sequel.expr(:views) + 1)
Or just this:
DB[:blogs].where(:id => params[:id]).
update('views = views + 1')
Rails is mostly syntactic sugar, not a woodoo magic. In your case the most efficient way to perform a task is:
DB[:blogs].update_all("views = views + 1", ["id = ?", params[:id]])
This would generate the query (say id = 1):
UPDATE "blogs" SET views = views + 1 WHERE (id = 1)

get distinct record from 3 tables using join in codeigniter

i have three tables
cases,clients,attendance
in cases
id start_date end_date client_id status
1 2012-12-30 2013-01-30 1 new starts
2 2012-12-31 2013-01-31 2 probation
in clients
id Name dob gender status
1 TOM 1987-01-30 M A
2 JERRY 1985-01-31 F D
in attendance
id client_id date status
1 1 2013-01-30 A
2 1 2013-01-31 P
i need result like this
case_id case_start_date case_end_date client_id Name
att_date atte_status
1 2012-12-30 2013-01-30 1 TOM
2013-01-30,2013-01-31 A,P
is this possible? i'm a self learner and i don't have good idea in join query please any body help me....
try this..
$this->db->select('ca.*,ci.Name,a.date,a.status');
$this->db->from('cases'.' ca');
$this->db->join('clients'.' ci','ca.client_id=ci.id','left');
$this->db->join('attendance'.' a','a.client_id=ci.id','left');
return $this->db->get();
go through the user guide if u want to read more about join and active records...
Here's a very simple example to get you started with any number of join common fun for all
Construcor Code
Construct $joins as array:
$joins = array(
array(
'table' => 'table2',
'condition' => 'table2.id = table1.id',
'jointype' => 'LEFT'
),
);
Example function handling joins as an array:
public function get_joins($table, $columns, $joins)
{
$this->db->select($columns)->from($table);
if (is_array($joins) && count($joins) > 0)
{
foreach($joins as $k => $v)
{
$this->db->join($v['table'], $v['condition'], $v['jointype']);
}
}
return $this->db->get()->result_array();
}

Resources