ASP.NET OData v3 vs Excel 2013: ignoring pagination? - c#

I'm trying to integrate an OData Web Api with Excel 2013 but I'm facing some troubles
Scenario:
Large database view with ~40 millions rows (MySQL)
Database-first EDMX on top of it (Entity Framework 6.1.0)
EntitySetController.Get() to supply data to the clients (WebApi 2.1)
Excel 2013 to consume OData feed
My server side code had to take into account the huge data that is behind, so I decorated my Get() with [Queryable(PageSize=50)]
public class SerieValuesController : EntitySetController<SerieValue, int>
{
#region DB Property
private EDMWarehouseViewsContainer _DB = null;
public EDMWarehouseViewsContainer DB
{
get
{
if (_DB == null)
_DB = new EDMWarehouseViewsContainer();
return _DB;
}
}
#endregion
[Queryable(PageSize=50)]
public override IQueryable<SerieValue> Get()
{
var options = this.QueryOptions;
IQueryable results = DB.SerieValues;
if (options.Filter != null)
{
results = options.Filter.ApplyTo(results, new ODataQuerySettings());
}
if (options.Top != null)
{
results = options.Top.ApplyTo(results, new ODataQuerySettings());
}
return results as IQueryable<SerieValue>;
}
protected override SerieValue GetEntityByKey(int id)
{
SerieValue entity = DB.SerieValues.Find(id);
return entity;
}
}
If I try to get data in a browser, with these URLs
http://mymachine.lan/odata/SerieValues (this gets correctly the first 50 rows in the view, along with a oData.nextLink node)
http://mymachine.lan/odata/SerieValues?$skip=50 (this get correctly the next 50 rows)
When I try to consume this feed from Excel 2013, it starts downloading the data automatically, page by page, until the memory blows.
So I changed my [Queryable] decoration as this
[Queryable(PageSize=50, MaxSkip=5000)]
After checking in the browser ($skip=4999 works, $skip=5000 works, $skip=5001 gives an error), I tried to download the data in excel again.
Unfortunately Excel stops at 5000 giving a Server Error and no data is displayed.
How can I make it work?

Yes, Excel will ignore paging when achieving data from OData service.
Since you set MaxSkip=5000, it will fail when the excel tries to get the 5001th record. So what is your expected behavior? If you wanna control the amount of return, you can combine $skip and $top in your query, and set MaxSkip and MaxTop in service to control the maximum value.

Related

ASP.NET Core MVC - Can not find the simple way to display the data from database

Total beginner here. I am having problems displaying data from the database. The code below fetches the data from the row with "id" successfully.
Public IActionResult Item(int id)
{
var ItemInDb = _context.Items.Find(id);
if(ItemInDb == null)
{
return NotFound();
}
return View(ItemInDb);
}
However, I can not find the simple way to display this data in corresponding view. Any help is appreciated.

Asp.net MVC real time application performance

i'm trying to create an asp.net mvc web application ,some pages need to show the data in "real time" ,this data is on a sql server database ,the data is changing always
i created a stored procedure in sql server , i call this procedure in my controller using Entity framework linq and send the result to the browser using ajax
i used outputcashing to minimize the number of execution of the stored procedure ,
in the same controller there is multiple methode that use the same stored procedure ,every methode execute the same procedure ,
how to emprove the performance of my application ,
is there a way to execute the stored procedure only one time for all the controller ??
this is my controller my objective is to minimize the use of the database
[OutputCache(Duration = 20, VaryByParam = "*")]
public class JobsETLController : Controller
{
private ETL_REP_MAUIEntities db = new ETL_REP_MAUIEntities();
public ObjectResult<BIOGetETLJobs_Result> ETLJobs;
public JobsETLController()
{
ETLJobs =db.BIOGetETLJobs();
}
public ActionResult Indexp()
{
var y = from xx in ETLJobs
where xx.etat!="Completed"
orderby xx.etat ascending
select xx;
return PartialView(y);
}
public ActionResult IndexpAll()
{
var y = from xx in ETLJobs
where xx.etat == "Completed"
select xx;
return PartialView(y);
}
If your server is not in a web farm (multiple servers) then you can cache the data in the Asp.net Cache (this is not output cacheing, it's data cacheing). You simply set a 5 minute time limit on the expiration of the data (you say the data needs to update every 5 minutes) so that when a controller needs the data it first checks the cache, and if it's not there it will then execute the stored procedure.
MyData items;
items = (MyData)Cache["MyData"];
if(items == null)
{
items = DoQueryToReturnItems();
Cache.Add("MyData", items, null, DateTime.Now.AddMinutes(5), ..);
}
It's even possible to setup the cache item to be dependent upon a SqlDependency so that when the data changes, the cache can be updated.

Manage/Update Records in ASP.NET With Redis using ServiceStack

I'm coming from a SQL Server background, and experimenting with Redis in .NET using ServiceStack. I don't mean for Redis to be a full replacement for SQL Server, but I just wanted to get a basic idea of how to use it so I could see where we might make good use of it.
I'm struggling with what I think is a pretty basic issue. We have a list of items that are maintained in a couple of different data stores. For the sake of simplicity, assume the definition of the item is basic: an integer id and a string name. I'm trying to do the following:
Store an item
Retrieve an item if we only know its id
Overwrite an existing item if we only know its id
Show all the items for that specific type
And here's some of the code I've put together:
public class DocumentRepositoryRedis
{
private static string DOCUMENT_ID_KEY_BASE = "document::id::";
public IQueryable<Document> GetAllDocuments()
{
IEnumerable<Document> documentsFromRedis;
using (var documents = new RedisClient("localhost").As<Document>())
{
documentsFromRedis = documents.GetAll();
}
return documentsFromRedis.AsQueryable();
}
public Document GetDocument(int id)
{
Document document = null;
using (var redisDocuments = new RedisClient("localhost").As<Document>())
{
var documentKey = GetKeyByID(document.ID);
if (documentKey != null)
document = redisDocuments.GetValue(documentKey);
}
return document;
}
public void SaveDocument(Document document)
{
using (var redisDocuments = new RedisClient("localhost").As<Document>())
{
var documentKey = GetKeyByID(document.ID);
redisDocuments.SetEntry(documentKey, document);
}
}
private string GetKeyByID(int id)
{
return DOCUMENT_ID_KEY_BASE + id.ToString();
}
}
It all seems to work - except for GetAllDocuments. That's returning 0 documents, regardless of how many documents I have stored. What am I doing wrong?
The typed Redis client also gives you access to the non-typed methods - since Redis ultimately doesn't know or care about your object types. So when you use the client.SetEntry() method, it bypasses some of the typed client's features and just stores the object by a key. You'll want to use the client.Store method since it goes ahead and creates a SET in Redis with all the object IDs related to your type. This SET is important because it's what the GetAll method relies on to serve back all the objects to you. The client.Store method does infer the ID automatically so you'll want to play around with it.
You'd change your GetDocument(int id) and SaveDocument(Document document) methods to use the client.GetById(string id) method, and you'd use client.Store(T value) method. You won't need your GetKeyByID() method anymore. I believe your Document object will need an "Id" property for the typed client to infer your object ID.

WCF web service: response is 200/ok, but response body is empty

I am creating a WCF web api service. My problem is that some methods return a 200/OK response, but the headers and the body are empty.
In setting up my web service, I created an ADO.NET Entity Data Model. I chose ADO.NET DbContext Generator when I added a code generation item. In the Model.tt document, I changed HashSet and ICollection to List. I built my website.
It used to be that when I coded a method to return a List of an entity (like List<Customer> or List<Employee> in the Northwind database), it worked fine. Over time, I could not return a List of any of those, and could only grab one entity. Now, it's gotten to a point where I can return a List<string> or List<int>, but not a List or an instance of any entity. When I try to get a List<AnyEntity>, the response is 200/OK, but the response headers and body are empty.
I have tried using the debugger and Firefox's Web Console. Using FF's WC, I could only get an "undefined" status code. I am not sure where to go from here.
EDIT: In trying to grab all Areas from the database, I do this:
[WebGet(UriTemplate = "areas")]
public List<a1Areas> AllAreas()
{
return context.a1Areas.ToList();
}
I would appreciate any more methods for debugging this. Thanks in advance.
Found the answer, thanks to Merlyn!
In my Global.asax file, I forgot to comment out two lines that took care of proxies and disposing of my context object. The code is below:
void Application_BeginRequest(object sender, EventArgs e)
{
var context = new AssignmentEntities();
context.Configuration.ProxyCreationEnabled = false;
HttpContext.Current.Items["_context"] = context;
}
void Application_EndRequest(object sender, EventArgs e)
{
var context = HttpContext.Current.Items["_context"] as AssignmentEntities;
if (context != null)
{
context.Dispose();
}
}

manually updating database table values are not reflecting in webpage - aspnet mvc

i noticed some wierd problem i.e i have built a web page on which information comes from database table named "school", when i change some data in that table manually from mssql the web page data is still same as previous, its not gettin' changed, i dn't know how it is possible.
this is my action controller
public ActionResult SchoolDetails(string id,_ASI_School schoolDetails)
{
schoolDetails = SchoolRepository.GetSchoolById(id);
return View(schoolDetails);
}
This is my view
=Html.Encode(Model.SchoolName)
= Html.Encode(Model.SchoolAddress)
= Html.Encode(Model.SchoolEmail)
code for GetSchoolById()..
private static ASIDataContext db = new ASIDataContext();
public static _ASI_School GetSchoolById(string schoolId)
{
return db._ASI_Schools.SingleOrDefault(x => x.SchoolId == schoolId);
}
try putting this above your SchoolDetails ActionResult
[OutputCache( Duration=0)]
MVC does some really nice server side caching as well that clearing the cache on the browser does not fix.

Categories

Resources