Blazor Server with Entity Framework core, How call DB methods Asyncronously - asp.net-core-3.1

I creating balzor server app with ASP.net core 3.1 and Entity framework core.
The problem is that since Db call takes a while to get back record and there is no built in async into EF core, i decided to delay pulling rows after few seconds once page loads.
But the problem is that my HTML does not update after code has run.
Without Task Delay i can see data. Why is it not updating my UI/HTML ?
Html
#if (_allRequestForHelp.Count > 0)
{
#foreach (var item in _allRequestForHelp)
{
}
}
protected override void OnInitialized()
{
telemetryClient.TrackPageView("RegisterForHelp");
// want to run this async other page hangs until the data comesback
Task.Delay(2000).ContinueWith(t => loadPreviousRequestForHelps());
base.OnInitialized();
}
private async Task loadPreviousRequestForHelps()
{
if (appStateInfo.IsAuthenticated)
{
_allRequestForHelp = (from b in dbContext.RequestHelp where b.UserID.ToString() == appStateInfo.UserID orderby b.UTCDateCreated descending select b).ToList();
StateHasChanged();
}
}

I used the async version OnInitialized
protected async override Task OnInitializedAsync()
everything else remains same and it is working now

Related

ASP.NET Core 2 Controller PUT method failing with Concurrency Core

I have an ASP.NET Core 2.0 Site that has a scaffolded controller built directly from a simple model and simple context. I seeded the data by simply checking for the number of records in the GET method and if 0, then I added 100 records. GET is retrieving records as I would expect repeatedly.
I'm using the inmemory database provider.
services.AddDbContext<MyDbContext>
(opt => opt.UseInMemoryDatabase("CodeCampInMemoryDb"));
When I do a PUT with a record that I know existed in my GET, I get a concurrency error as shown at the bottom of this post. I've not used this method of changing the EntityState of a record I created myself, so I'm not sure how this was suppose to work in the first place, but clearly now it is not working.
Maybe it has something to do with a transaction being processed on the inmemory database? I'm not sure how to avoid that if that is the problem.
// PUT: api/Sessions/5
[HttpPut("{id}")]
public async Task<IActionResult> PutSessionRec([FromRoute] int id, [FromBody] SessionRec sessionRec)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != sessionRec.Id)
{
return BadRequest();
}
_context.Entry(sessionRec).State = EntityState.Modified;
try
{
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException xx)
{
if (!SessionRecExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return NoContent();
}
Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException: Attempted to update or delete an entity that does not exist in the store.
at Microsoft.EntityFrameworkCore.Storage.Internal.InMemoryTable`1.Update(IUpdateEntry entry)
at Microsoft.EntityFrameworkCore.Storage.Internal.InMemoryStore.ExecuteTransaction
If you marked a property as a Timestamp and don't provide it, you will get this exception every time. You either need to load the entity with the latest Timestamp and update that (not ideal) or you have to send the Timestamp down to the client and have the client send it back up (correct way). However, if you are using an older version of JSON serialization, you have to convert the byte[] to base 64 and then convert it back.

WPF : Update View Model when DB Changes (Concurrency Issue)

I'm currently working on WPF app that is architectured as follows:
MVVM
Entity Framwork 4 (with LINQ).
WCF service that pool Database to get data (Oracle).
I Make my WFC call in my View Model Class and put my data in an ObsevableCollections.
Db Changes occurs from a another app.
So my app does not do any write actions on the DB what-so-ever (Zéro), it only reads data and displays it on the UI.
How can I make my app to be quickly responsive to DB changes, I read about the following solutions but I'm confused and don't know what to use:
Pooling DB every n seconds with a DispatcherTimer (seems to be too much work cause data changes every millisecond)
SqlDependency, searched all over the internet but didn't find a proper implementation with EF.
As I said, db changes every millisecond (financial data from other sources),
How can resolve this?
Thank you.
i tried the code bellow and it seemed to be working okay for the moment (but i still have some doubts about that infinit loop), let me know what you thing :
public class MyViewModel
{
BackgroundWorker _bgWorker ;
//some props
//some funcs
protected internal MyViewModel(Session session)
{
Session = session;
RefreshData();
}
protected void RefreshData()
{
try
{
_bgWorker = new BackgroundWorker
{
WorkerReportsProgress = true,
WorkerSupportsCancellation = true
};
_bgWorker.DoWork += bgDoWork;
if (!_bgWorker.IsBusy)
{
_bgWorker.RunWorkerAsync();
}
}
catch (Exception)
{
_bgWorker.CancelAsync();
}
}
private void bgDoWork(object sender, DoWorkEventArgs e)
{
var worker = (BackgroundWorker)sender;
while (!worker.CancellationPending)
{
//Thread.Sleep(1000); should i keep this or not ?
Proxy(); // WCF calls
}
}
}

Entity Framework Core 1.0 CurrentValues.SetValues() does not exist

I'm attempting to update an entity and its related child entities using Entity Framework Core 1.0 RC 1, where the entities are detached from DbContext. I've done this previously using a solution similar to the one described in this answer.
However, it seems that we are no longer able to do the following using Entity Framework 7:
DbContext.Entry(existingPhoneNumber).CurrentValues.SetValues();
Visual Studio complains that:
EntityEntry does not contain a definition for 'CurrentValues'
etc...
I presume this means that this has not (yet?) been implemented for EF Core 1.0? Apart from manually updating the properties, is there any other solution?
As you have noticed, this API is not implemented yet in EF Core. See this work item: https://github.com/aspnet/EntityFramework/issues/1200
I know this is an old question but I ran into this issue today, and it appears it still isn't implemented in EF Core. So I wrote an extension method to use in the meantime that will update any object's properties with the matching values of any other object.
public static class EFUpdateProperties
{
public static TOrig UpdateProperties<TOrig, TDTO>(this TOrig original, TDTO dto)
{
var origProps = typeof(TOrig).GetProperties();
var dtoProps = typeof(TDTO).GetProperties();
foreach(PropertyInfo dtoProp in dtoProps)
{
origProps
.Where(origProp => origProp.Name == dtoProp.Name)
.Single()
.SetMethod.Invoke(original, new Object[]
{
dtoProp.GetMethod.Invoke(dto, null) });
}
);
return original;
}
}
Usage:
public async Task UpdateEntity(EditViewModel editDto)
{
// Get entry from context
var entry = await _context.Items.Where(p => p.ID == editDto.Id).FirstOrDefaultAsync();
// Update properties
entry.UpdateProperties(editDto);
// Save Changes
await _context.SaveChangesAsync();
}

Create async methods to load data from database using EF

how does one write an async method that gets data from database, using DbContext and .NET 4.0?
public Task<List<Product>> GetProductsAsync()
{
// Context.Set<Product>().ToList();
}
so we can await somewhere for result of this method
// somewhere
List<Product> products = await repository.GetProductsAsync();
What is important is that I do not want to use thread pool thread for this task, since this is an IO task, and I need to support framework 4.0, and EF6 had added support for async methods only in 4.5, if I am not mistaken.
Not possible, SaveAsync is wrapped with:
#if !NET40
Source: https://github.com/aspnet/EntityFramework6/blob/master/src/EntityFramework/DbContext.cs#L335
Installing Entity Framework 6 is available as a Nuget Package and works also with .NET 4. In EF6, async
DB calls can be done like this example:
public static async Task<List<Customer>> SelectAllAsync()
{
using (var context = new NorthWindEntities())
{
var query = from c in context.Customers
orderby c.CustomerID ascending
select c;
return await query.ToListAsync();
}
}
Here, a DbContext is instantiated in a using block and the query will search the Northwind database for all its customers and order ascending by primary key CustomerID. The method needs to be decorated with async keyword and must return a task of the desired type T, here a list of customers. The result will then be return by using the ToListAsync() method in this case and one must remember to use the await keyword. There are additional Async methods in EF6, such as SaveChangesAsync, SingleOrDefaultAsync and so on. Also, async methods in C# should following this naming conventions according to guidelines.
To get started test the code above in Visual Studio, just create a new Console Application solution, type: install-package EntityFramework in the Package Manager Console and add an edmx file pointing to a local Northwind database. The main method will then just call the method above like this:
class Program
{
static void Main(string[] args)
{
Stopwatch sw = Stopwatch.StartNew();
var task = CustomHelper.SelectAllAsync();
task.Wait();
Console.WriteLine("Got data!");
List<Customer> data = task.Result;
Console.WriteLine(data.Count);
Console.WriteLine("Async op took: " + sw.ElapsedMilliseconds);
sw.Stop();
sw.Start();
//data =
//var data = CustomHelper.SelectAll();
//Console.WriteLine("Got data!");
//Console.WriteLine(data.Count);
//Console.WriteLine("Sync operation took: " + sw.ElapsedMilliseconds);
Console.WriteLine("Press any key to continue ...");
Console.ReadKey();
}
}
I see that the async operation takes a bit longer than the sync operation, so the async db call will have some time penalty but allows asynchronous processing, not freezing the calling code awaiting the result in a blocking fashion.

using the enterprise library cache application blocks in asp.net mvc2

I tried to use the cache application blocks of the microsoft enterprise library. I have used the MS Enterprise Library V5.0
Here is the sample code i have made, inside the home controller's index method.
Person p = new Person(10, "person1");
ICacheManager cacheMgr = CacheFactory.GetCacheManager("myCache");
ViewData["Message"] = "Welcome to ASP.NET MVC!";
if (Session["currsession"] != null)
{
if (!cacheMgr.Contains(p.pid.ToString()))
{
Response.Write("item is not in cache");
return View(p);
}
else
{
Response.Write("item is still in cache");
return View(p);
}
}
else
{
Session["currsession"] = 1;
cacheMgr.Add(p.pid.ToString(), p, CacheItemPriority.High, null, new SlidingTime(TimeSpan.FromSeconds(10)));
return View(cacheMgr.GetData(p.pid.ToString()));
}
The person class i use in the model has just a constructor with 2 public properties. Nothing special features are used.
Now, is this the right procedure to use the caching of the enterprise library caching blocks. If not, how else can i code this block of code in an efficient manner.
Also, i get the response as item is not in cache only after 20 second delay. Is there any mistake in the implementation of the code or is there a theory behind the caching in detail.
Kindly suggest the best practice for this usage.
Since you specify a sliding expiration of 10 seconds, that means that you will get item is not in cache if you wait more than 10 seconds between reloading the page.
Load first time in session => no message
Reload => in cache
Reload => in cache
Wait 10 seconds
Reload => not in cache
Is this what you're seeing?
Old answer:
The enterprise caching application block is probably way more than you need. My favorite cache is FubuMVC's Cache (just include FubuCore.dll). You can get a very similar implementation by using a ConcurrentDictionary with a "missing element" delegate. Here's an example: http://social.msdn.microsoft.com/Forums/en/parallelextensions/thread/37bbc361-6851-43db-9e90-80cc7e6ac15f
FubuMVC Cache example:
public class PersonCache
{
private Cache _Cache = new Cache();
public PersonCache()
{
_Cache.OnMissing = key => MyDatabase.People.GetById(key);
}
public Person GetById(int id)
{
return _Cache[id];
}
}