Nhibernate Criteria retrieve child of parent with restriction on other child of parent - nhibernate

I need to be able to write the following query as a Criteria.
SELECT hist.*
FROM
Administration admin
INNER JOIN Item item ON item.AdministrationId = admin.AdministrationId
INNER JOIN ItemHistory hist ON hist.ItemId = item.ItemId
WHERE
item.itemId = #param
and hist.IsError =
(
SELECT (CASE status.errorType
WHEN 'Warning' THEN 0
ELSE 1
END
)
FROM
AdminStatus status
WHERE
status.AdministrationId = admin.AdministrationId
AND status.Group = 'Issues'
)
I'm pretty sure I'll need to do the sub query as a detached criteria:
var status = DetachedCriteria.For<AdminStatus>("status");
status.CreateAlias("status.Administration", "admin");
status.Add(Restrictions.Eq("status.Group", "Issues"));
status.SetProjection(Projections.Property("AdministrationId"));
status.SetProjection(Projections.Conditional(
Restrictions.Eq("status.errorType", "Warning"),
Projections.Constant(0),
Projections.Constant(1)));
But I'm not sure how to join that with my primary criteria:
var criteria = Session.CreateCriteria<ItemHIstory>("hist");
criteria.CreateAlias("ItemHistory.Item", "item");
criteria.CreateAlias("item.Administration", "admin");

But I'm not sure how to join that with my primary criteria:
Methods from Subqueries class glue detached sub-query with main criteria. Subqueries.PropertyEq in you case:
var criteria = Session.CreateCriteria<ItemHIstory>("hist");
criteria.CreateAlias("ItemHistory.Item", "item");
criteria.CreateAlias("item.Administration", "admin");
criteria.Add(Subqueries.PropertyEq("hist.IsError ", status))
And regarding detached criteria. Alias creation seems unnecessary:
var status = DetachedCriteria.For<AdminStatus>("status");
status.Add(Restrictions.EqProperty("status.AdministrationId", "admin.AdministrationId"));
status.Add(Restrictions.Eq("status.Group", "Issues"));
status.SetProjection(Projections.Conditional(
Restrictions.Eq("status.errorType", "Warning"),
Projections.Constant(0),
Projections.Constant(1)));

Related

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();

Trying to make query on condition

I read most of the solutions here with similar questions and it did not solve my problem and I cannot find anything online that can help me.
I am trying to make query on condition where user_id = session user_id but I get error when I make INNER join
ambiguous column name
for this
public List<CartModelClass>getCarts1(){
SQLiteDatabase db = getReadableDatabase();
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
String[] sqlSelect = { "ID" , "user_id", "food_id", "quantity", "price", "origin", "destination","description","company_name","search_id"};
String sqltable2 = "OrderDetails LEFT JOIN OrderDetails WHERE user_id LIKE '%%' ";
qb.setTables(sqltable2);
Cursor c = qb.query(db,sqlSelect, null, null ,null ,null ,null);
final List<CartModelClass> result = new ArrayList<>();
if (c.moveToFirst()) {
do {
result.add(new CartModelClass(
c.getString(c.getColumnIndex("user_id")),
c.getString(c.getColumnIndex("food_id")),
c.getString(c.getColumnIndex("quantity")),
c.getString(c.getColumnIndex("price")),
c.getString(c.getColumnIndex("origin")),
c.getString(c.getColumnIndex("destination")),
c.getString(c.getColumnIndex("description")),
c.getString(c.getColumnIndex("company_name")),
c.getString(c.getColumnIndex("search_id"))
));
} while (c.moveToNext());
}
return result;
}
so I changed InnerJoin and made it just table where user_id like"%%" but I only get the last user_id who added to cart and show all data for all users
I want to show only added cart for user_id = session user_id so i can use it in here
loadListFood
private void loadListFood(){
sessionManager= new SessionManager(getActivity());
final Hashmap<String, String> user = sessionManager.getUserDetail();
user.get(USER_ID);
listdata = new Database(this.getContext.getCarts1());
for(CartModelClass order : listdata)
user_id = order.getUser_id
if(user.get(USER_ID).equals(user_id)){
listdata = new Database(this.getContext()).getCarts();
adapter = new CartAdapter(listdata, this.getContext());
recyclerView.setAdapter(adapter);
int total = 0;
for (CartModelClass order : listdata) {
total += (Integer.parseInt(order.getPrice())) * (Integer.parseInt(order.getQuantity()));
Locale locale = new Locale("en", "US");
NumberFormat fmt = NumberFormat.getCurrencyInstance(locale);
txtTotalPrice.setText(fmt.format(total));
}
}else {
Toast.makeText(getContext(), "No Cart Added", Toast.LENGTH_LONG).show();
}
}
You are self joining the table OrderDetails.
In this case you must set aliases to both copies of the table, like:
OrderDetails as o1 LEFT JOIN OrderDetails as o2 ...
Now in the ON clause you must qualify the column names properly, like:
ON o1.user_id = o2.something
If you don't, you get that error message, because the column name user_id could belong to either of the 2 copies of the table.
Also:
What is session user_id? Is it a column name?
If it is then the problem is that it contains a space in its name.
Enclose it in square brackets, so the statemnet should be:
OrderDetails as o1 LEFT JOIN OrderDetails as o2
ON o1.user_id = o2.[session user_id]

LEFT join AND command in yii2

I want to write a query in yii2
and i dont know how to write it
i tried few things from documentaion but its not working
here is my query
SELECT notification.*,event.title,user.firstname,user.lastname FROM notification
LEFT JOIN event ON event.id = notification.source_id
AND notification.activity_type = "checkin"
Where user.firstname in (select id from user where user_id=1)
LEFT JOIN user ON user.id = notification.source_id
AND notification.activity_type = "friend"
Where user.firstname in (select id from user where user_id=1)
and here is the query i write for now,i need to add AND function just like its in the query
$query ->select(['notification.*,event.title,user.firstname,user.lastname'])
->from('notification')
->leftJoin('event', 'event.id = notification.source_id')
->leftJoin('user', 'user.id = notification.source_id');
Have you tried the following:
$query ->select(['notification.*,event.title,user.firstname,user.lastname'])
->from('notification')
->leftJoin('event', 'event.id = notification.source_id AND notification.activity_type = "checkin" ')
->leftJoin('user', 'user.id = notification.source_id AND notification.activity_type = "friend"');

JOIN and LEFT JOIN equivalent in LINQ with Method Syntax

I am converting a SQL query to LINQ that creates a left join with 1-to-1 mapping, and it has to be in Method Syntax. I have been pulling off my hair trying to accomplish this to no veil. I can do it in Lambda Syntax. Below is the example query I am trying to run. They are not actual code. Would someone point out what I am doing wrong?
SQL:
SELECT item.*, item_status.*
FROM item
LEFT JOIN item_status
ON item.ID = item_status.itemID
AND item_status.FLAGGED = true
WHERE item.published_date > "2008-06-19"
LINQ:
var linq_query = (
from selected_item in item
join selected_item_status in item_status
on selected_item.ID equals item_status.itemID into joined
from item_status in joined.DefaultIfEmpty()
where item_status.FLAGGED = true
select new {selected_item, selected_item_status}).ToList();
The join ... into becomes a GroupJoin and the second from becomes a SelectMany:
var linq_query = Item
.GroupJoin(
item_status.Where(x => x.selected_item_status.FLAGGED), // EDIT: Where clause moved here.
selected_item => selected_item.ID,
selected_item_status => selected_item_status.itemID,
(selected_item, joined) => new
{
selected_item,
statuses = joined.DefaultWithEmpty(),
})
.SelectMany(x => x.statuses.Select(selected_item_status => new
{
x.selected_item,
selected_item_status,
}))
// EDIT: Removed where clause.
.ToList();
It looks like the Where makes the left outer join unnecessary, as null statuses will be filtered out anyway.
EDIT: No, upon reviewing the SQL it looks like your LINQ query is slightly incorrect. It should be:
var linq_query = (
from selected_item in item
join selected_item_status
in (
from status in item_status
where status.FLAGGED
select status)
on selected_item.ID equals item_status.itemID into joined
from item_status in joined.DefaultIfEmpty()
select new {selected_item, selected_item_status}).ToList();

Problems with Left join Query LinqToSql

IBookingRepository bookingResp = new BookingRepository();
IQueryable<bookingTest> bookings = bookingResp.GetAllBookingsByView();
var grid = new System.Web.UI.WebControls.GridView();
grid.DataSource = from booking in bookings
join f in getallAttendees on booking.UserID equals f.UserID into fg
from fgi in fg.DefaultIfEmpty() //Where(f => f.EventID == booking.EventID)
where
booking.EventID == id
select new
{
EventID = booking.EventID,
UserID = booking.UserID,
TrackName = booking.Name,
BookingStatus = booking.StatusID,
AttendeeName = booking.FirstName,
// name = account.FirstName,
AmountPaid = booking.Cost,
AttendeeAddress = booking.DeliveryAdd1,
City = booking.DeliveryCity,
Postcode = booking.Postcode,
Date = booking.DateAdded,
hel = fgi == null ? null : fgi.HelmetsPurchased }// Product table
Hi, the above query doesnt executes it gives an error: The specified LINQ expression contains references to queries that are associated with different contexts. Any one can spot the what the problem is with the query.
I think that your getAllAttendees is from a different context than bookings so you won't be able to join them. To give a more exact answer you need to show where bookings and getAllAttendees comes from.