Where to insert 'orderby' expression in this linq-to-sql query - linq-to-sql

var result = db.PhotoAlbums.Select(albums => new PhotoAlbumDisplay
{
AlbumID = albums.AlbumID,
Title = albums.Title,
Date = albums.Date,
PhotoID = albums.Photos.Select(photo => photo.PhotoID).FirstOrDefault().ToString()
});
Wherever I try to put orderby albums.AlbumID descending I get error. Someone knows solution?
Thanks!

This should work:
var result = db.PhotoAlbums.Select(albums => new PhotoAlbumDisplay
{
AlbumID = albums.AlbumID,
Title = albums.Title,
Date = albums.Date,
PhotoID = albums.Photos.Select(photo => photo.PhotoID).FirstOrDefault().ToString()
})
.OrderByDescending(item => item.AlbumID);
In query syntax:
var result = from albums in db.PhotoAlbums
orderby albums.AlbumID descending
select new PhotoAlbumDisplay
{
AlbumID = albums.AlbumID,
Title = albums.Title,
Date = albums.Date,
PhotoID = albums.Photos.Select(photo => photo.PhotoID).FirstOrDefault().ToString()
};

If you want to use the query syntax, you'll have to start with "from X select" and work from that. In this case it'd be easier to just use the .OrderBy() method to order the results.

Is this what you're looking for?
var result = db.PhotoAlbums.Select(albums => new PhotoAlbumDisplay
{
AlbumID = albums.AlbumID,
Title = albums.Title,
Date = albums.Date,
PhotoID = albums.Photos.Select(photo => photo.PhotoID).FirstOrDefault().ToString()
})
.OrderByDescending(a=>a.AlbumID);

Related

Object of class Illuminate\Database\Eloquent\Collection could not be converted to int in laravel

I have a table named purchase_details in where during purchase, I am storing many items' purchase record at a time. During purchase also I am updating items table column opening_balance based on purchased items id, Now I am getting trouble when trying to sum 'purchase details' table quantity's value with 'items' table old opening_balance - in the controller, I am trying something like this-
public function store(Request $request)
{
$grandTotal = $request->input('grand_total');
$paidAmount = $request->input('paid_amount');
$purchase = new Purchase;
$purchase->no = $request->input('no');
$purchase->purchase_date = Carbon::parse($request->purchase_date)->format('Y-m-d');
$purchase->notes = $request->input('notes');
$purchase->supplier_id = $request->input('supplier');
$purchase->total_quantity = $request->input('total_quantity');
$purchase->grand_total = $grandTotal;
$purchase->paid_amount = $paidAmount;
$purchase->due_amount = abs($grandTotal - $paidAmount);
$purchase->save();
$itemDetails = [];
$itemIds = $request->input('itemIds');
$itemQuantities = $request->input('itemQuantities');
$itemPrices = $request->input('itemPrices');
$itemTotals = $request->input('itemTotals');
$orderNotes = $request->input('orderNotes');
foreach ($itemTotals as $key => $total) {
$itemDetails[] = [
'item_id' => $itemIds[$key],
'quantity' => $itemQuantities[$key],
'unit_price' => $itemPrices[$key],
'total_price' => $itemTotals[$key],
];
$openingBalance = Item::where('id', $itemIds[$key])->get(['opening_balance']);
DB::table('items')
->where('id', $itemIds[$key])
->update(['opening_balance' => $openingBalance + $itemQuantities[$key]]);
}
$purchase->purchaseDetails()->createMany($itemDetails);
return back();
}
You use collection as int, edit your code:
$openingBalance = Item::select(['opening_balance'])->where('id', $itemIds[$key])->first()->opening_balance;

How to convert this request to LINQ?

SELECT StepID, count() as nb FROM Question GROUP BY StepID ORDER by nb;
You should probably go through the basics of LINQ. Microsoft Docs has a whole section dedicated to LINQ: https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/
If you have your data in a List called as questions of type, List<Question> then you should be able to convert your Query like this:
var ret = from q in questions
group q by q.StepId into grouped
let count = grouped.Count()
orderby count
select new { StepId = grouped.Key, nb = count };
Query comprehension syntax:
from q in questions
group q by q.StepId into g
select new { StepId = g.Key, Count = g.Count() } into stepCount
orderby stepCount.Count
select stepCount;
Exact same in method syntax (which I prefer, since it can all query syntax can plus more and also often is more compact):
questions
.GroupBy(q => q.StepId)
.Select(g => new { StepId = g.Key, Count = g.Count() })
.OrderBy(stepCount => stepCount.Count)
Variant using another GroupBy overload:
questions
.GroupBy(q => q.StepId, (key, values) => new { StepId = key, Count = values.Count() })
.OrderBy(stepCount => stepCount.Count);

Return multiple aggregate columns in LINQ

I would like to translate the following SQL into LINQ:
SELECT
(Select count(BidID)) as TotalBidNum,
(Select sum(Amount)) as TotalBidVal
FROM Bids
I've tried this:
from b in _dataContext.Bids
select new { TotalBidVal = b.Sum(p => p.Amount), TotalBidNum = b.Count(p => p.BidId) }
but get an error "Bids does not contain a definition for "Sum" and no extension method "Sum" accepting a first argument of type "Bids" could be found.
How can I do this in LINQ?
Thanks
CONCLUDING:
The final answer was:
var ctx = _dataContext.Bids;
var itemsBid = (from b in _dataContext.Bids
select new { TotalBidVal = ctx.Sum(p => p.Amount), TotalBidNum = ctx.Count() }).First();
You can write this query using GroupBy. The Lambda expression is as follows:
var itemsBid = db.Bids
.GroupBy( i => 1)
.Select( g => new
{
TotalBidVal = g.Sum(item => item.Amount),
TotalBidNum = g.Count(item => item.BidId)
});
You could try this out. The variable b is an entity (for every iteration) while ctx is an entityset which has the extension methods you need.
var ctx = _dataContext.Bids;
var result = ctx
.Select( x => new
{
TotalBidVal = ctx.Sum ( p => p.Amount ),
TotalBidNum = ctx.Count( p => p.BidId )
} )
.First();
here's an alternative to scartag's solution:
(from b in _dataContext.Bids.Take(1)
select new
{
TotalBidVal = _dataContext.Bids.Sum(p => p.Amount),
TotalBidNum = _dataContext.Bids.Count()
}).Single();
Although there's no real reason you can't just say:
var result = new
{
TotalBidVal = _dataContext.Bids.Sum(p => p.Amount),
TotalBidNum = _dataContext.Bids.Count()
};
It hits the database twice, but its very readable
You could do it using the Aggregate Clause.
Aggregate t In _dataContext.Bids
Into TotalBidNum = Count(BidID),
TotalBidVal = Sum(Amount)
If you're using Fx4+ or an extension dll for Fx2, you could also benfit from parallelism by using
Aggregate t In _dataContext.Bids.AsParallel

LINQ-to-SQL load keyword from variable

public IQueryable<ArticleDisplay> SearchNumberOfArticles(int articleNr, string order)
var result = (
from category in db.ArticleCategories
join article in db.Articles on category.CategoryID equals article.CategoryID
orderby article.Date order
select new ArticleDisplay
{
CategoryID = category.CategoryID,
CategoryTitle = category.Title,
ArticleID = article.ArticleID,
ArticleTitle = article.Title,
ArticleDate = article.Date,
ArticleContent = article.Content
}
).Take(articleNr);
In PHP this would work, but in C# it doesn't. So, how to load keyword from variable and "print" it inside query? Here is order suppose to be replaced with descending or ascending.
Thanks
You can use an if statement
IQueryable<ArticleDisplay> SearchNumberOfArticles(int articleNr, string order)
{
................
var articles = from category in db.ArticleCategories
join article in db.Articles
on category.CategoryID equals article.CategoryID
select article;
if (string.IsNullOrEmpty(order) || order == "ascending" || order = "asc")
{
articles = articles.OrderBy(a => a.Date).Take(articleNr);
}
else
{
articles = articles.OrderByDescending(a => a.Date).Take(articleNr);
}
.............
}

Help to build LINQ query

I have SQL database as follows
alt text http://img97.imageshack.us/img97/5774/dbimage.jpg
Now I want to filter the restaurant_detail table for the parameters:
1. cuisine 2. area
Can you help me to build LINQ query?
I presume you have a model generated either with LINQ to SQL or Entity Framework. Also, I'm assuming foreign key relationships have been set.
var details = db
.Cuisines
.Where(c => c.Cuisine=="something")
.SelectMany(c => c.RestaurantCuisines)
.Select(rc => rc.Restaurant.RestaurantDetails)
.Where(rd => rd.Area=="something")
;
Done with the linq query using following lines of code :
c = from q in dc.restaurant_cuisines
where q.cuisine.cuisine1.Contains(cuisine)
&& q.restaurant.price.ToString().Length == price.Length
select new NearBy { NearById = q.restaurant.id, NearByLongitude = (double)q.restaurant.longitude, NearByLatitude = (double)q.restaurant.latitude };
}
int[] ids = new int[c.Count()];
var lon = from q1 in dc.area_maps where q1.area.ToLower() == area.ToLower() select q1.longtitude;
var lat = from q1 in dc.area_maps where q1.area.ToLower() == area.ToLower() select q1.latitude;
foreach(NearBy n in c)
{
result = calcDistNew((double)lat.FirstOrDefault(), (double)lon.FirstOrDefault(), n.NearByLatitude, n.NearByLongitude);
ids[i++] = n.NearById;
}
var r = from q in dc.restaurant_details
where 1 == 1 &&
(ids).Contains(q.restaurant_id)
select new Restaurant
{
Restora_id = q.restaurant_id.ToString(),
Name = q.restaurant.name,
Foodtype = q.restaurant.foodtype.foodtype1,
Avg_rating = q.restaurant.avg_rating.ToString(),
Featured = q.restaurant.featured.ToString(),
CuisineList = getCuisine(q.restaurant_id),
Restora_type = q.type,
Distance = Math.Round(calcDistNew((double)lat.FirstOrDefault(), (double)lon.FirstOrDefault(), (double)q.restaurant.latitude, (double)q.restaurant.longitude), 2),
Newarrival = q.restaurant.newarrival.ToString(),
CountRecord = ids.Length.ToString()
};
var d = r.AsEnumerable().OrderBy(t => t.Distance);
var g = d.Take(recordSize + 10).Skip(recordSize);
return g.ToList();
Please note that above displayed code generated with some changes from the initial requirements.