ListView with 6000 rows c# - c#

I am with a little issue on handling with one of my applications.
I have a Vessel's historic which is shown on a ListView, but until now I have never needed to show all the data inside this history (the user was using kind of a filter to get what he needed), but now one of the managers want to see all data through the application (they was receiving the full data through an excel report).
The biggest issue is because its 6000 rows with 21 columns each one and when I try to select all the data it takes something between 5 minutes to fully load, but more than that the user need to add new, edit or copy the history, which brings him to a new update on the list with more 5 minutes to load.
I don't quite know how is the best way to handle with this and I wanted your help!

I would actually split the information into sections. Rather than loading 6,000 rows plus columns all at once, why don't you use something like alphabetize the information? Use a different ListView for A-G, then another ListView for H-O, then so on and so forth. That why it would cut down the time it took to query all of the information.

Related

Blazor Server Side - Load more 50 data

Good Day Everyone
I'm creating a Blazor Server Side application with card style on my home page, I did not use javascript on loading those data, it's just simple razor and c#. Now it loads almost 2000+ data, this makes my app slow, so what I want to do is to load 50 data first, then there is a load more below that will load 50 data, my idea is to insert the 50 on the object where the first 50 is, but I think this will also cause a bulk on the data projected on the page, and it might cause a problem if it reaches a 3000+, is there a way to do this on the Blazor Server-Side?
Thanks and regards
Blazor does not have built-in pagination. You'll have to do that yourself in your C# code that sends the data to your frontend/razor component(s). There are Blazor frameworks that can handle that for you, of course (Google for MudBlazor or Radzen).
You can either create your own logic to load more results on each click of a button (not really hard to manage that with a SQL query).
Or you can try component virtualization, which I suspect is the closest built-in option to what you want:
https://learn.microsoft.com/en-us/aspnet/core/blazor/components/virtualization?view=aspnetcore-6.0
Edit Note:
I just noticed Bennyboy1973 mentioned this.
I suppose I just expounded on it for no reason, haha.
I know this is an old question, but for anyone else who may stumble across this problem.
Blazor has a "Virtualize" component that you can make use of. Simply put, it only renders and displays records that would be visible on screen. As you scroll in the list, it would then render the next set of records and so on, freeing up the resources that would normally be used rendering the full dataset.
To compliment the "Virtualize" component, Blazor has a ItemsProvider delegate method which you can make use of; allowing you to set it up so that instead of loading the full 2000+ record set, it only loads the amount of records needed for the current viewspace of your app. Then like the Virtualize, as you scroll it will query your dataset for the next X amount of records and then render them, and so on.
Setting up the initial "Virtualize" component is easy:
Let's say you load your cards as below
<div style="height:800px; overflow-y:scroll">
#foreach (var card in allCardDetails)
{
<MyCard #key="card.Id" Title="#card.Title" Details="#card.Details" />
}
</div>
What this will result in, is all Cards being rendered for all data records. (This includes rendering of Cards that aren't even visible onscreen.)
To implement the Virtualize component, you simply change up the code snippet to resemble the following
<div style="height:800px; overflow-y:scroll">
<Virtualize Items="#allCardDetails" Context="card">
<MyCard #key="card.Id" Title="card.Title" Details="#card.Details" />
</Virtualize>
</div>
Now, only the Cards that would be visible within the region of the DIV will be rendered, and as you scroll down in the DIV it will proceed to render the next Cards that would be visible and so on.
This would greatly aid in screen jittering or rendering (The lag). If you want to take it a step further, to limit the amount of data that is queried from your server at initial load, you can make use of the ItemsProvider delegate method to achieve this.
Virtualize with ItemsProvider:
<div style="height:800px; overflow-y:scroll">
<Virtualize Context="card" ItemsProvider="#loadCardDetails">
<MyCard #key="card.Id" Title="card.Title" Details="#card.Details" />
</Virtualize>
</div>
We've removed the Items field, and replaced it with the ItemsProvider as the Datasource is now mutable; determined by the ItemsProvider. Lastly, we need to create the ItemsProvider method (in this case called "loadCardDetails") which will dynamically load the records as they are needed.
private async ValueTask<ItemsProviderResult<CardDetails>> loadCardDetails(ItemsProviderRequest request)
{
//It would be a good idea, at page load, to get a count of all records and
//and store in an accessible variable.
//For the sake of this example, I'll include it here.
var totalCount = DbContext.CardDetails.Count();
//This portion, determines how many records need to be loaded next
//Math.Min is used to ensure that we don't try to load more records than
//is available.
//Eg. We have 50 records, but Vitualize is requesting 60 records (more than
//we have) instead it will only attempt to get the 50 we have and return it
var numCardDeets = Math.Min(request.Count, totalCount - request.StartIndex);
//This portion get's the next set of data records to the count of our
//"numCardDeets" value.
var results = DbContext.CardDetails.Skip(request.StartIndex).Take(numCardDeets);
//Finally, it returns the result set to the Virtualize component to render.
return new ItemsProviderResult<CardDetails>(results, totalCount);
}
And that's it. If all is setup correctly, the Virtualize component will now only load the Data that would fit on your screen (from your datasource) and render it; then as you scroll down it loads the next set of Data, and renders it.
This example is made under the assumption you make use of EntityFramework to retrieve data from a database. The implementation of how you get the Data from your datasource will vary depending on what or where your datasource is.
I'll just note here:
request.StartIndex and request.Count are managed by the ItemsProvider; it keeps track of it's own current index and request number (number of records being requested)

dynamically populate table in aspx page

So I'm reading data out of a database and want to display it on a webpage like this:
Name Age Fav# ...other info
Bob 11 15
Joe 13 4
I want to make a website that updates the contents of its table based on the database. I know the number of columns that the database has but not necessarily the number of rows.
I was thinking just writing the .aspx file and generating the HTML and values when the database is read, but I was looking at some similar stackoverflow questions and they advise against it? The suggestion was to create a template .aspx file and just populate it, but how would you do that if you don't know the exact number of rows to make?
Also if I programatically write my own Something.aspx files and create a Something.aspx.cs file, will they automatically link together?
I'm new to ASP.net and C#, so I'm not sure if there's an easier way of doing this.
Since you're using ASP.NET I'd suggest using GridView control to display table data. It has a lot more possibilities (like built in paging and sorting). And you do not need to know in advance number of rows - GridView will render whatever is thrown at it, turning on paging if nessesery

How to improve the performance of a Gridview that contains 10000 data records in c# asp.net?

I had an interview Question .
Q. how to improve performance of a Gridview contains 100000 Records of data(Datasource might be XML or DB) in c# asp.net ?
I was just blinking as i had no answer for this .Please Give me the solution for this. If possible please give one demo.
No gridview should contain 100000 records.
Your data source may contain 10 times that number of records, it doesn't matter. If you present a user more than 100 records on screen, it would be difficult to work with that data.
Select a datasource that supports paging for the gridview, that way you are only working with the number of records to be displayed on screen.
For a database you can use something like SqlDataSource.
The default XmlDataSource does not support paging, in such cases the grid will have all records in memory and handle paging itself. For xml with large number of records consider using an ObjectDataSource, where you can implement paging yourself.
If you have a choice, always select a data source that supports paging.
To fix such a GridView, I think a good approach would be to:
Add paging (as others have already pointed out)
Add filtering/searching
Add a cap/limit for maximum number of rows shown
The filtering + max limit for results is (in my opinion) a good way to keep the size of the grid manageable. If the max limit is hit using some specified set of filters (=search terms) you could show a message about it to the user and encourage him/her to specify a more specific search if necessary.
As stated before, a gridview should not hold so many rows.
In your interview, they wanted to see if you can say that its bad implemented rather then to check your programming skill.
But if one insist for good performance, I would suggest to use Repeater instead of Gridview.
Cheers,
Ran

a large paged GridView, Rollup and Grand Totals with SQLdataSource

If I get my dataset into a DataTable then I can do with it as I like, but I have the complexity of handling sort, paging and caching manually. I'm trying to avoid this for now.
If I instead use a SQLdataSource that's all free.
I need a grand total row, the contents of which I display outside the gridview.
I know that I can get that by hooking the RowBound event in IIS and summing up every row I see, but that seems a but complicated and pedestrian.
I know that I can manually do a SQLdataSource.Select on my SQLdataSource (it's cached) to extract a DataTable from that, and then use DataTable.Compute to sum the columns, but this seems a bit hack and I'm not sure how efficient two "selects" really is even with caching.
My preferred approach would be to get SQLserver to do the grunt work, using Group By Rollup, which gives me the last row of the result set with the totals I want in it. The problem then is that I have the totals row in my GridView, which I don't want in there as I need to put the totals somewhere else (no point in having them on the last page where they can be sorted and paged). I guess I could again catch row bound events and make this totals row invisible, but that's a bit hack and may confuse the paging.
So I'm wondering if there's a neat way to do this?
When you mean large data set, I am assuming a million plus?
I would suggest caching the result of the grand total. There's no need to recalculate that every time you view/page the table. Create observable events when you create/update/delete the table to refresh the grand total info? (Because I do not see you mentioning filtering, which is the only time when the grand total changes without the dataset changing)
Or maybe have the grand total info on a timed expire cache. If the data is suffeciently large and volatile, sometimes you would have to consider the business value of having an exact uptodate grand total. Usually there's no business value in that. A somewhat close enough value from a few sec ago is fine.
As for SqlDataSource control, personally I hate it. Whatever happened to the Presentation/Logic/Data tiers?!...

is there a good way to display too much information in ASP.NET?

I find myself in a quandry that I think I know the solution to but I'd like to ask the field. I have an ASP.NET (C# 2.0 framework) page within a site which is used as a lookup. Standard gridview control, 5 columns of data, hyperlink for the 6th column to do something with record the user wants to select.
My question goes towards how to best display 'a possible' 100k records in that gridview? As it stands right now I'd sprout a few more gray hairs before it ever returns a rendered result. The gridview, for its realestate can display about 20 rows of data on the screen at a time, so paging the data still gives me 5000 pages. Adding in a rolodex-type search on A-Z the largest return set on 'J' gives me 35000 records (where alas 'X' only has 54).
Do I just break the rolodex up smaller or is there a better way to handle a situation like this?
thanks in advance!
edit: I already have the stored procedure which populates this set up for paging like GenericTypeTea suggested, again even with paging on 'J' that would give me 1750 pages. The reason I have that much data is that the amount of participants on the given auto policy. The admin needs to be able to search for a given name, or a partial. 'Jones' has 1209 records and 'Smith' has 2918 so even that makes for a rebust result set.
edit #2: added 'a possible' 100k, there is no guarentee that the account will have that many records, on the other hand it could have more :(
AutoComplete is your friend :)
Just let people enter the first 2 or 3 characters then filter your searches.
With a dataset that large I don't think paging would make that much sense.
jQuery has a nice example page AutoComplete Examples
Filters. Don't show that much data. Show the first x records. And beyond that, the user will need to be more precise with their search. Nobody will look through 100k records for the one they want. I'd limit it to a couple hundred at most (10 pages, 20 per page).
Advise the user how many results there were though, or give some clue so they know that there were many that aren't shown, and they need to be more specific in their search
It seems to me like adding search capabilities would be more efficient than filtering or paging.

Categories