Codeigniter: from sql to activerecord, what is the wrong? - sql

I want to try change my sql code to active record, here is the original code and active record try. And the error message. Please tell me where is my wrong? Thanks.
SELECT `emlakilan`.`id`, `emlakdurum`.`durum`,`emlaktip`.`tip`,`semtler`.`semt`,`emlakilan`.`fiyat`,`emlakilan`.`tarih`,`resim`.`r1` FROM ucburcak.`emlakilan`
INNER JOIN `semtler` ON `emlakilan`.`semtId` = `semtler`.`semtid`
INNER JOIN `emlaktip` ON `emlakilan`.`emlakTipId` = `emlaktip`.`id`
INNER JOIN `emlakdurum` ON `emlakilan`.`emlakDurumId` =`emlakdurum`.`id`
LEFT JOIN `resim` ON `emlakilan`.`resimId` = `resim`.`id`
WHERE `emlakdurumId`=3 ORDER BY `emlakilan`.`id` DESC LIMIT 4;
//and here active record function
public function kucuk_ilan($durum ='3') // $durum:1=>tümü 2=>kiralık 3=>satılık 4=>takas
{
$query = $this->db->select('emlakilan.id, emlakdurum.durum, emlaktip.tip, semtler.semt, emlakilan.fiyat, emlakilan.tarih, resim.r1')
->from('emlakilan')
->join('semtler','emlakilan.semtId' === 'semtler.semtid','inner')
->join('emlaktip','emlakilan.emlakTipId'==='emlaktip.id','inner')
->join('emlakdurum','emlakilan.emlakDurumId'==='emlakdurum.id','inner')
->join('resim','emlakilan.resimId'==='resim.id','left')
->where('emlakdurumId'===$durum)
->order_by('emlakilan.id','desc')
->limit(4);
$query = $this->db->get('emlakilan');
return $query->result_array();
}
And, error message:
Error Number: 1066
Not unique table/alias: 'emlakilan'
SELECT emlakilan.id, emlakdurum.durum, emlaktip.tip, semtler.semt, emlakilan.fiyat, emlakilan.tarih, resim.r1 FROM (emlakilan, emlakilan) INNER JOIN semtler ON INNER JOIN emlaktip ON INNER JOIN emlakdurum ON LEFT JOIN resim ON WHERE 0 IS NULL ORDER BY emlakilan.id desc LIMIT 4
Filename: C:\Program Files\EasyPHP-12.1\www\3burcak\system\database\DB_driver.php
Line Number: 330
Thanks for help.

So 1. remove the 'from' line
2. the joins where wrong
try this:
public function kucuk_ilan($durum ='3') // $durum:1=>tümü 2=>kiralık 3=>satılık 4=>takas
{
$query = $this->db->select('emlakilan.id, emlakdurum.durum, emlaktip.tip, semtler.semt, emlakilan.fiyat, emlakilan.tarih, resim.r1')
->from('emlakilan')
->join('semtler','emlakilan.semtId = semtler.semtid','inner')
->join('emlaktip','emlakilan.emlakTipId = emlaktip.id','inner')
->join('emlakdurum','emlakilan.emlakDurumId = emlakdurum.id','inner')
->join('resim','emlakilan.resimId = resim.id','left')
->where('emlakdurumId', $durum)
->order_by('emlakilan.id','desc')
->limit(4);
$query = $this->db->get('emlakilan');
return $query->result_array();
}

Related

SQL Statement with inner join to LINQ

I need to convert my SQL statement to LINQ.
SELECT
dbo.Transactions.TypeRefID,
dbo.TransactionItems.ItemRefID,
SUM(dbo.TransactionItems.Quantity) AS Qty
FROM
dbo.TransactionItems
LEFT OUTER JOIN
dbo.Transactions ON dbo.TransactionItems.TransactionRefID = dbo.Transactions.TransactionID
GROUP BY
dbo.Transactions.TypeRefID, dbo.TransactionItems.ItemRefID
HAVING
(dbo.Transactions.TypeRefID = 1)
AND (dbo.TransactionItems.ItemRefID = 5)
I tried converting the above statement into LINQ and this is what I've done.
var query = from t in db.Transaction
join i in db.TransactionItem on t.TransactionID equals i.TransactionRefID
where t.TypeRefID == 1 && i.ItemRefID == 5
group i by new
{
t.TypeRefID,
i.ItemRefID
} into g
select new
{
TypeRefID = g.Key.TypeRefID,
ItemRefID = g.Key.ItemRefID,
Quantity = g.Sum(q => q.Quantity)
};
When I run my code I get error "System.Linq.Queryable.FirstOrDefault(...) returned null"
I'm using it like this
if (query != null)
string qty = query.FirstOrDefault().Quantity.ToString();
The error is called on "query.FirstOrDefault().Quantity.ToString()"
How to avoid this error?

How to write join query with multiple column - LINQ

I have a situation where two tables should be joined with multiple columns with or condition. Here, I have a sample of sql query but i was not able to convert it into linq query.
select cm.* from Customer cm
inner join #temp tmp
on cm.CustomerCode = tmp.NewNLKNo or cm.OldAcNo = tmp.OldNLKNo
This is how i have write linq query
await (from cm in Context.CustomerMaster
join li in list.PortalCustomerDetailViewModel
on new { OldNLKNo = cm.OldAcNo, NewNLKNo = cm.CustomerCode } equals new { OldNLKNo = li.OldNLKNo, NewNLKNo = li.NewNLKNo }
select new CustomerInfoViewModel
{
CustomerId = cm.Id,
CustomerCode = cm.CustomerCode,
CustomerFullName = cm.CustomerFullName,
OldCustomerCode = cm.OldCustomerCode,
IsCorporateCustomer = cm.IsCorporateCustomer
}).ToListAsync();
But this query doesn't returns as expected. How do I convert this sql query into linq.
Thank you
You didn't tell if list.PortalCustomerDetailViewModel is some information in the database, or in your local process. It seems that this is in your local process, your query will have to transfer it to the database (maybe that is why it is Tmp in your SQL?)
Requirement: give me all properties of a CustomerMaster for all CustomerMasters where exists at least one PortalCustomerDetailViewModel where
customerMaster.CustomerCode == portalCustomerDetailViewModel.NewNLKNo
|| customerMaster.OldAcNo == portalCustomerDetailViewModel.OldNLKNo
You can't use a normal Join, because a Join works with an AND, you want to work with OR
What you could do, is Select all CustomerMasters where there is any PortalCustomerDetailViewModel that fulfills the provided OR:
I only transfer those properties of list.PortalCustomerDetailViewModel to the database that I need to use in the OR expression:
var checkProperties = list.PortalCustomerDetailViewModel
.Select(portalCustomerDetail => new
{
NewNlkNo = portalCustomerDetail.NewNlkNo,
OldNLKNo = portalCustomerDetail.OldNLKNo,
});
var result = dbContext.CustomerMasters.Where(customerMaster =>
checkProperties.Where(checkProperty =>
customerMaster.CustomerCode == checkProperty.NewNLKNo
|| customerMaster.OldAcNo == checkProperty.OldNLKNo)).Any()))
.Select(customerMaster => new CustomerInfoViewModel
{
Id = customerMaster.Id,
Name = customerMaster.Name,
...
});
In words: from each portalCustomerDetail in list.PortalCustomerDetailViewModel, extract the properties NewNKLNo and OldNLKNo.
Then from the table of CustomerMasters, keep only those customerMasters that have at least one portalCustomerDetail with the properties as described in the OR statement.
From every remaining CustomerMasters, create one new CustomerInfoViewModel containing properties ...
select cm.* from Customer cm
inner join #temp tmp
on cm.CustomerCode = tmp.NewNLKNo or cm.OldAcNo = tmp.OldNLKNo
You don't have to use the join syntax. Adding the predicates in a where clause could get the same result. Try to use the following code:
await (from cm in Context.CustomerMaster
from li in list.PortalCustomerDetailViewModel
where cm.CustomerCode == li.NewNLKNo || cm.OldAcNo = li.OldNLKNo
select new CustomerInfoViewModel
{
CustomerId = cm.Id,
CustomerCode = cm.CustomerCode,
CustomerFullName = cm.CustomerFullName,
OldCustomerCode = cm.OldCustomerCode,
IsCorporateCustomer = cm.IsCorporateCustomer
}).ToListAsync();
var result=_db.Customer
.groupjoin(_db.#temp ,jc=>jc.CustomerCode,c=> c.NewNLKNo,(jc,c)=>{jc,c=c.firstordefault()})
.groupjoin(_db.#temp ,jc2=>jc2.OldAcNo,c2=> c2.OldNLKNo,(jc2,c2)=>{jc2,c2=c2.firstordefault()})
.select(x=> new{
//as you want
}).distinct().tolist();

Left outter join linq

How do i change the training events into a left outer join in training events im very basic at linq so excuse my ignorance its not retrieve records that don't have any trainnevent reference attached to it
var q = from need in pamsEntities.EmployeeLearningNeeds
join Employee e in pamsEntities.Employees on need.EmployeeId equals e.emp_no
join tevent in pamsEntities.TrainingEvents on need.TrainingEventId equals tevent.RecordId
where need.EmployeeId == employeeId
where need.TargetDate >= startdate
where need.TargetDate <= enddate
orderby need.TargetDat
It's best to use where in combination with DefaultIfEmpty.
See here: LEFT JOIN in LINQ to entities?
var query2 = (
from users in Repo.T_Benutzer
from mappings in Repo.T_Benutzer_Benutzergruppen.Where(mapping => mapping.BEBG_BE == users.BE_ID).DefaultIfEmpty()
from groups in Repo.T_Benutzergruppen.Where(gruppe => gruppe.ID == mappings.BEBG_BG).DefaultIfEmpty()
//where users.BE_Name.Contains(keyword)
// //|| mappings.BEBG_BE.Equals(666)
//|| mappings.BEBG_BE == 666
//|| groups.Name.Contains(keyword)
select new
{
UserId = users.BE_ID
,UserName = users.BE_User
,UserGroupId = mappings.BEBG_BG
,GroupName = groups.Name
}
);
var xy = (query2).ToList();
Which is equivalent to this select statement:
SELECT
T_Benutzer.BE_User
,T_Benutzer_Benutzergruppen.BEBG_BE
-- etc.
FROM T_Benutzer
LEFT JOIN T_Benutzer_Benutzergruppen
ON T_Benutzer_Benutzergruppen.BEBG_BE = T_Benutzer.BE_ID
LEFT JOIN T_Benutzergruppen
ON T_Benutzergruppen.ID = T_Benutzer_Benutzergruppen.BEBG_BG

SQL Query in LINQ to Entities

Can anyone tell me,how to write this query in LINQ?
select a.UTP_NAME, b.UPS_NAME, c.USS_NAME from
TB_UTILIDADE_PUBLIC_UTP a inner join
TB_UTILIDADE_PUBLIC_SECTOR_UPS b on
a.UPS_ID = b.UPS_ID
inner join TB_UTILIDADE_PUBLIC_SUBSECTOR_USS c
on a.USS_ID = c.USS_ID and a.UPS_ID = c.UPS_ID /* IMPORTANT LINE! */
Thanks.
Creating a new anonymous type allows you to join with multiple criteria
var query = from a in context.TB_UTILIDADE_PUBLIC_UTP
join b in context.TB_UTILIDADE_PUBLIC_SECTOR_UPS
on a.UPS_ID equals b.UPS_ID
join c in context.TB_UTILIDADE_PUBLIC_SUBSECTOR_USS
on new { a.USS_ID, a.UPS_ID } equals new { c.USS_ID, c.UPS_ID }
select new
{
a.UTP_NAME,
b.UPS_NAME,
c.USS_NAME
};

LINQ to SQL - How to add a where clause to a left join?

This LINQ query expression emits a left join and works:
from p in Prices
join ip in ItemPrices
on new { p.PriceId, ItemId = 7 } equals
new { ip.PriceId, ip.ItemId }
into priceItemPrice
from pip in priceItemPrice.DefaultIfEmpty()
select new
{
pricesPriceId = p.PriceId,
z = (int?)pip.PriceId,
p.Content,
p.PriceMinQ
}
SQL emitted:
-- Region Parameters
DECLARE #p0 Int = 7
-- EndRegion
SELECT [t0].[priceId] AS [pricesPriceId],
[t1].[priceId] AS [z],
[t0].[price] AS [Content],
[t0].[priceMinQ] AS [PriceMinQ]
FROM [price] AS [t0]
LEFT OUTER JOIN [itemPrice] AS [t1]
ON ([t0].[priceId] = [t1].[priceId])
AND (#p0 = [t1].[itemId])
How can I get it to emit the SQL below? It just has the where clause tacked on the end. A where clause is not accepted under the "from pip" and a where lambda expression before DefaultIfEmpty() doesn't work. I know I can filter it out in the select, but that's not what I need.
SELECT [t0].[priceId] AS [pricesPriceId],
[t1].[priceId] AS [z],
[t0].[price] AS [Content],
[t0].[priceMinQ] AS [PriceMinQ]
FROM [price] AS [t0]
LEFT OUTER JOIN [itemPrice] AS [t1]
ON ([t0].[priceId] = [t1].[priceId])
AND (#p0 = [t1].[itemId])
WHERE [t1].[priceId] is null
Update
Oy vey, my mistake, the where clause did work - for some reason VS2008 was not behaving and giving me grief and my stomach was growling. I tested back in LinqPad and the where clause was fine. So this little addition did work:
...
from pip in priceItemPrice.DefaultIfEmpty()
*** where pip.ItemId == null ***
select new
...
Here is a sample of how OneDotNetWay has done something similar. I've tried to take their example and match up your query.
var query = p in Prices
join ip in ItemPrices
on
new { p.PriceId, ItemId = 7 }
equals
new { ip.PriceId, ip.ItemId }
into priceItemPrice
from pip in priceItemPrice.DefaultIfEmpty()
select new
{
pricesPriceId = p.PriceId,
z = (int?)pip.PriceId,
p.Content,
p.PriceMinQ
}