Errors using a LINQ query in a Silverlight application - linq

I am trying to consume the WCF services using Silverlight application in Sharepoint.
It's going to display all the data from a list in a grid. Somehow it is throwing a error.
Cannot convert lambda expression to type 'system.Delegate' because it is not a delegate type.
using the generic type 'system.collections.generic.ienumerable' requires 1 type arguments
SLprojectsCRUD2010WCF.sharepointservice.list1item' is a type but is used like a variable.
How can this be solved?
private SharePointService.SkinnyBlondeDataContext _context;
public MainPage()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(LayoutRoot_Loaded);
}
private void ShowProjects()
{
// Declare the LINQ query
var projectsQuery = (from p in _context.Tasks
select p) as DataServiceQuery<SharePointService.TasksItem>;
// Execute the LINQ query
projectsQuery.BeginExecute((IAsyncResult asyncResult) => Dispatcher.BeginInvoke(() =>
{ // Runs in the UI thread
// EndExecute returns
IEnumerable < TasksItem > this.dataGridProjects.ItemsSource = projectsQuery.EndExecute(asyncResult).ToList();
}), projectsQuery);
}
private void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
{
// Get the context
_context = new SharePointService.SkinnyBlondeDataContext(
new Uri("http://vanir0269/_vti_bin/listdata.svc", UriKind.Absolute));
ShowProjects();
}

Until your source code is formatted properly it'll be a pain to see what the LINQ problem is, but the lambda expression problem is easy: Dispatcher.BeginInvoke takes a Delegate, and lambda expressions can only be converted into specific delegate types. This is easy to fix:
projectsQuery.BeginExecute((IAsyncResult asyncResult) => {
Action action = () => {
// Code in here
};
Dispatcher.BeginInvoke(action, null);
});

Related

ToPagedListAsync() - The provider for the source IQueryable doesn't implement IDbAsyncQueryProvider

I have been trying to sort out this for hours and could not find a solution.
I am using a Web Api MVC project and trying to convert an IEnumerable list to a paged list async. I'm able to compile but I'm still getting a runtime error on the ToPagedListAsync() line.
The provider for the source IQueryable doesn't implement IDbAsyncQueryProvider. Only providers that implement IDbAsyncQueryProvider can be used for Entity Framework asynchronous operations. For more details see http://go.microsoft.com/fwlink/?LinkId=287068."
1st Layer:
public async Task<IEnumerable<MatchingCriteria>> GetMatchingCriterias(int id)
{
return await _ctx.MatchingCriterias.Include(mc => mc.RuleDefinition).Where(mc => mc.RuleDefinitionId == id).ToListAsync();
}
2nd Layer:
internal async Task<IEnumerable<MatchingCriteria>> GetMatchingCriterias(int id)
{
using (CrawlerDbContext db = new CrawlerDbContext())
{
var matchCriteriaMgr = new MatchingCriteriaManager(db);
return await matchCriteriaMgr.GetMatchingCriterias(id);
}
}
Controller:
public async Task<ActionResult> Index(int? id, string sortOrder, string currentFilter, string searchString, int? page){
var matchingCriterias = await _crawlerProvider.GetMatchingCriterias(id.Value);
//...
IQueryable<MatchingCriteria> matchCrit = matchingCriterias.AsQueryable();
//Error here -> return View(await matchCrit.ToPagedListAsync(pageNumber, pageSize));
}
if I do instead in the controller:
var matchingCriterias = _db.MatchingCriterias.Include(mc => mc.RuleDefinition);
then:
return View(await matchingCriterias.ToPagedListAsync(pageNumber, pageSize)
That works well!
I could return a DbSet on the nested methods but I could not use the ToListAsync() in the 1st layer;
Is there a way to make the list IQueryable?Any other ideas or suggestions?
Well, I fixed it myself by creating an AsyncQueryable extension as mentioned here
Then I could call the pagedListAsync() method like bellow:
return View(await matchingCriterias.AsAsyncQueryable().ToPagedListAsync(pageNumber, pageSize)

UI gets stuck while loading lot of data from realm

I am trying to show 10,000 contacts on listview in xamarin forms using realm. But whenever user traverse to contact listing screen
it gets freezed and loads after a while.
Moreover , i have provided an option to search from list as well and that too gets stuck as search if performing on UI thread.
Following is the code to load data from realm
public override async Task Initialize(Object data )
{
private Realm _realmInstance = getRealm();
if (contactList != null)
{
contactList.Clear();
}
contactList = _realmInstance.All<Contact>().OrderByDescending(d => d.contactId).ToList();
// here the binding happens with realm data
contacts = new ObservableCollectionFast<Contact>(contactList);
}
public ObservableCollectionFast<Contact> contacts
{
get { return items; }
set
{
items = value;
OnPropertyChanged("contacts");
}
}
as it was taking time in loading i thought to fetch realm data in background and bind it on UI thread as follows
but that is throwing error
realm accessed from incorrect thread
await Task.Run(() => {
contactList = _realmInstance.All<Contact>().OrderByDescending(d => d.contactId).ToList();
});
if (contactList.Count() > 0)
{
ContactListView = true;
AddContactMsg = false;
}
else
{
AddContactMsg = true;
}
Device.BeginInvokeOnMainThread(() =>
{
contacts = new ObservableCollectionFast<Contact>(contactList);
});
i wanted to try limiting the results by using TAKE function of LINQ but unfortunately its not supported by realm yet. not sure how i can smoothly load records from realm to listview.
EDIT
as per the SushiHangover i have changed things from IList to IQueryable
public IQueryable<Contact> contacts
{
get { return items; }
set
{
items = value;
OnPropertyChanged("contacts");
}
}
public override async Task Initialize(Object data )
{
_realmInstance = getRealm();
contacts = dbContactList= _realmInstance.All<Contact>();
}
so far search is working pretty smoothly but IQueryable change leads to another issue. on repeatedly performing following steps results in app crash
tap on list item
detail page gets open then press back
scroll down to few records
perform step 1 and repeat
this results into stackoverflow error
04-19 06:05:13.980 F/art ( 3943): art/runtime/runtime.cc:289]
Pending exception java.lang.StackOverflowError thrown by 'void
md5b60ffeb829f638581ab2bb9b1a7f4f3f.CellAdapter.n_onItemClick(android.widget.AdapterView,
android.view.View, int, long):-2' 04-19 06:05:13.980 F/art (
3943): art/runtime/runtime.cc:289] java.lang.StackOverflowError: stack
size 8MB
Link to entire log file
code to fire item click command is
public ICommand OnContactSelectCommand => new Command<Contact>(OnContactSelect);
following code will open ups a detail page
private async void OnContactSelect(Contact contact)
{
if (contact != null)
{
await NavigationService.NavigateToAsync<ContactDetailViewModel>(contact.mContactId);
}
}
Note:
when i replace IQueryable with List i do not face any error
somehow my issue is related to realm github thread where user is getting exception on listView.SelectedItem = null while using IQueryable
here is my code of list view item tap
private static void ListViewOnItemTapped(object sender, ItemTappedEventArgs e)
{
var listView = sender as ListView;
if (listView != null && listView.IsEnabled && !listView.IsRefreshing)
{
// have commented this line because it was crashing the app
//listView.SelectedItem = null;
var command = GetItemTappedCommand(listView);
if (command != null && command.CanExecute(e.Item))
{
command.Execute(e.Item);
}
}
}

How can I call an async command with a view model?

I have this code and I am wanting to move it into a view model:
resetButton.Clicked += async (sender, e) =>
{
if (App.totalPhrasePoints < 100 || await App.phrasesPage.DisplayAlert(
"Reset score",
"You have " + App.totalPhrasePoints.ToString() + " points. Reset to 0 ? ", "Yes", "No"))
App.DB.ResetPointsForSelectedPhrase(App.cfs);
};
I realize I will need to set up something like this:
In my XAML code;
<Button x:Name="resetButton" Text="Reset All Points to Zero" Command="{Binding ResetButtonClickedCommand}"/>
And in my C# code:
private ICommand resetButtonClickedCommand;
public ICommand ResetButtonClickedCommand
{
get
{
return resetButtonClickedCommand ??
(resetButtonClickedCommand = new Command(() =>
{
}));
}
But how can I fit the async action into a command?
You can try something like this:
(resetButtonClickedCommand = new Command(async () => await SomeMethod()));
async Task SomeMethod()
{
// do stuff
}
And to expand on already provided answer, if you need to pass a parameter to the command, you can use something like
(resetButtonClickedCommand = new Command<object>(async (o) => await SomeMethod(o)));
async Task SomeMethod(object o)
{
// do stuff with received object
}
You could replace object above by anything you want as well.
On further testing, this class may be overkill for most uses.
Despite the downvotes, chawala's answer works fine in my tests.
Importantly, the presence of async on the method declaration is sufficient to avoid blocking UI thread. Therefore, chawala's answer is "not broken"; does not merit those downvotes, imho.
To be clear: the explicit async => await answers are of course perfectly fine, without any issue. Use them if that gives you more confidence.
My answer was intended to make the call site cleaner. HOWEVER, maxc's first comment is correct: what I have done is no longer "identical" to the explicit async => await. So far, I haven't found any situation where that matters. Whether with or without async/await inside new Command, if you click a button several times quickly, all the clicks get queued. I've even tested with SomeMethod switching to a new page. I have yet to find any difference whatsoever to the explicit async/await. All answers on this page have identical results, in my tests.
async void works just as well as async Task, if you aren't using the Task result anyway, and you aren't adding any code to do something useful with any exceptions that occur during this method.
In this class code, see my comment "TBD: Consider adding exception-handling logic here.".
Or to put it another way: most devs are writing code where it makes no difference. If that's a problem, then its going to equally be a problem in their new Command(await () => async SomeMethod()); version.
Below is a convenience class. Using it simplifies combining commands with async.
If you have an async method like this (copied from accepted answer):
async Task SomeMethod()
{
// do stuff
}
Without this class, using that async method in a Command looks like this (copied from accepted answer):
resetButtonClickedCommand = new Command(async () => await SomeMethod());
With the class, usage is streamlined:
resetButtonClickedCommand = new AsyncCommand(SomeMethod);
The result is equivalent to the slightly longer code line shown without using this class. Not a huge benefit, but its nice to have code that hides clutter, and gives a name to an often-used concept.
The benefit becomes more noticeable given a method that takes a parameter:
async Task SomeMethod(object param)
{
// do stuff
}
Without class:
yourCommand = new Command(async (param) => await SomeMethod(param));
With class (same as the no-parameter case; compiler calls the appropriate constructor):
yourCommand = new AsyncCommand(SomeMethod);
Definition of class AsyncCommand:
using System;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows.Input;
namespace MyUtilities
{
/// <summary>
/// Simplifies using an "async" method as the implementor of a Command.
/// Given "async Task SomeMethod() { ... }", replaces "yourCommand = new Command(async () => await SomeMethod());"
/// with "yourCommand = new AsyncCommand(SomeMethod);".
/// Also works for methods that take a parameter: Given "async Task SomeMethod(object param) { ... }",
/// Usage: "yourCommand = new Command(async (param) => await SomeMethod(param));" again becomes "yourCommand = new AsyncCommand(SomeMethod);".
/// </summary>
public class AsyncCommand : ICommand
{
Func<object, Task> _execute;
Func<object, bool> _canExecute;
/// <summary>
/// Use this constructor for commands that have a command parameter.
/// </summary>
/// <param name="execute"></param>
/// <param name="canExecute"></param>
/// <param name="notificationSource"></param>
public AsyncCommand(Func<object,Task> execute, Func<object, bool> canExecute = null, INotifyPropertyChanged notificationSource = null)
{
_execute = execute;
_canExecute = canExecute ?? (_ => true);
if (notificationSource != null)
{
notificationSource.PropertyChanged += (s, e) => RaiseCanExecuteChanged();
}
}
/// <summary>
/// Use this constructor for commands that don't have a command parameter.
/// </summary>
public AsyncCommand(Func<Task> execute, Func<bool> canExecute = null, INotifyPropertyChanged notificationSource = null)
:this(_ => execute.Invoke(), _ => (canExecute ?? (() => true)).Invoke(), notificationSource)
{
}
public bool CanExecute(object param = null) => _canExecute.Invoke(param);
public Task ExecuteAsync(object param = null) => _execute.Invoke(param);
public async void Execute(object param = null)
{
// TBD: Consider adding exception-handling logic here.
// Without such logic, quoting https://learn.microsoft.com/en-us/archive/msdn-magazine/2013/march/async-await-best-practices-in-asynchronous-programming
// "With async void methods, there is no Task object, so any exceptions thrown out of an async void method will be raised directly on the SynchronizationContext that was active when the async void method started."
await ExecuteAsync(param);
}
public event EventHandler CanExecuteChanged;
public void RaiseCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
}
}
Re comments below about async void Execute. Both class Command and interface ICommand have method void Execute. Being compatible with those, means having the same method signature - so the usually recommended async Task MethodName() is not an option here. See links in my comments for discussion of the implications of having void here.
To instance AsyncCommand with a parameter, is correct this approach:
this.SaveCommand = new AsyncCommand((o) => SaveCommandHandlerAsync (o));
or is need
you can write this also:-
(resetButtonClickedCommand = new Command(DoSomething));
async void DoSomething()
{
// do something
}
Note :- It shows warning at SomeMethod.

ReactiveCollection and invalid cross-thread access

I'm developing my first app for Windows Phone 7.1 using Reactive UI, and I'm facing difficulties working with ReactiveCollection class.
My app is roughly about accessing the WP7 SQL CE engine (LINQ to SQL). I would like to perform data operations in background, using ReactiveAsyncCommand. Data from database should "automagically" appear in UI, therefore I decided to use ReactiveCollection as a proxy between database and UI.
Here's my model, so you could have a better idea:
public class EncounteredModel
{
public ReactiveCollection<Fact> FactsCollection;
public ReactiveCollection<FactEntry> FactEntriesCollection;
private EncounteredModel()
{
using (EncounteredDataContext db = new EncounteredDataContext())
{
FactsCollection = new ReactiveCollection<Fact>(from fact in db.Facts select fact);
FactEntriesCollection = new ReactiveCollection<FactEntry>(from factEntry in db.FactEntries select factEntry);
}
FactsCollection.ItemsAdded.Subscribe(fact => { using (var db = new EncounteredDataContext()) { db.Facts.InsertOnSubmit(fact); db.SubmitChanges(); } });
FactsCollection.ItemsRemoved.Subscribe(fact => { using (var db = new EncounteredDataContext()) { db.Facts.DeleteOnSubmit(fact); db.SubmitChanges(); } });
FactEntriesCollection.ItemsAdded.Subscribe(factEntry => { using (var db = new EncounteredDataContext()) { db.FactEntries.InsertOnSubmit(factEntry); db.SubmitChanges(); } });
FactEntriesCollection.ItemsRemoved.Subscribe(factEntry => { using (var db = new EncounteredDataContext()) { db.FactEntries.DeleteOnSubmit(factEntry); db.SubmitChanges(); } });
}
private static EncounteredModel instance;
public static EncounteredModel Instance
{
get
{
if (instance == null)
instance = new EncounteredModel();
return instance;
}
}
}
In my view model I've tried using 2 different variants:
Create a derived reactive collection and bind UI to it (With ReactiveCollection.CreateDerivedCollection() method. It's derived from the EncounteredModel.FactsCollection, for example.
Use ObservableAsPropertyHelper<IEnumerable<Fact>>, then subscribe to Model's ReactiveCollection Changed IObservable to populate the OAPH.
Both variants, unfortunately, give me "Invalid cross-thread access." Stack trace is generally the same for both variants, here's one for the variant 1 (shortened to the significant part):
at MS.Internal.XcpImports.CheckThread()
at System.Windows.DependencyObject.GetValueInternal(DependencyProperty dp)
at System.Windows.FrameworkElement.GetValueInternal(DependencyProperty dp)
at System.Windows.DependencyObject.GetValue(DependencyProperty dp)
at System.Windows.Controls.ItemsControl.get_ItemsHost()
at System.Windows.Controls.ItemsControl.OnItemsChangedHandler(Object sender, ItemsChangedEventArgs args)
at System.Windows.Controls.ItemContainerGenerator.OnItemAdded(Object item, Int32 index, Boolean suppressEvent)
at System.Windows.Controls.ItemContainerGenerator.System.Windows.Controls.ICollectionChangedListener.OnCollectionChanged(Object sender, NotifyCollectionChangedEventArgs args)
at System.Windows.Controls.WeakCollectionChangedListener.SourceCollectionChanged(Object sender, NotifyCollectionChangedEventArgs e)
at System.Windows.Controls.ItemCollection.NotifyCollectionChanged(NotifyCollectionChangedEventArgs e)
When I change to ReactiveCommand (not async one), everything's fine. Any ideas how to overcome this? Much thanks in advance.
ReactiveCollection doesn't proxy everything to the UI thread, if you add items to it from a worker thread, you will signal the UI on that same thread and get the crash.
However, one thing that ReactiveAsyncCommand does for you is give you back the results back on the UI thread, so you can do something like this:
var cmd = new ReactiveAsyncCommand();
cmd.RegisterAsyncFunc(() => getAllTheItems())
.Subscribe(theItems => theItems.ForEach(item => collection.Add(item)));
The Subscribe is guaranteed to be on the UI thread (if it isn't, that's a bug)

Accessing User in Entity partial class via OnContextCreated()?

All of my tables have common audit fields: modifiedBy,modifiedDateTime, etc.
I would like to have these automatically set, and can set most of them with the following code:
partial class myEntities
{
partial void OnContextCreated()
{
this.SavingChanges += new EventHandler(Entities_SavingChanges);
}
private void Entities_SavingChanges(object sender, EventArgs e)
{
IEnumerable<ObjectStateEntry> objectStateEntries =
from ose
in this.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified)
where ose.Entity != null
select ose;
var auditDate = DateTime.Now;
var auditUser = System.Web.HttpContext.Current.User.Identity.Name;//I wish
foreach (ObjectStateEntry entry in objectStateEntries)
{
ReadOnlyCollection<FieldMetadata> fieldsMetaData = entry.CurrentValues.DataRecordInfo.FieldMetadata;
FieldMetadata modifiedField = fieldsMetaData.Where(f => f.FieldType.Name == "ModifiedBy").FirstOrDefault();
if (modifiedField.FieldType != null)
{
string fieldTypeName = modifiedField.FieldType.TypeUsage.EdmType.Name;
if (fieldTypeName == PrimitiveTypeKind.String.ToString())
{
entry.CurrentValues.SetString(modifiedField.Ordinal, auditUser);
}
}
}
}
}
The problem is that there doesn't appear to be any way to get access to the current user. The app is intranet only, using Windows auth.
Is there a way to either pass in a parameter, or get access to the HttpContext (which doesn't seem like it would be a good idea, but I'm stuck)? Is there a way to populate the EventArgs with information?
Check out the section where the poster has overridden the SaveChanges method (6th code box down on the page). This way you can pass in the UserID and perform your audit and not have to use an event handler.

Resources