EF 4.1, database first and Many-to-Many relationships - How to get all sub-objects? - linq

Let's say I have the following tables in a database forming a Many-to-Many Relationship. And in an ASP.Net MVC project using EF 4.1, I have corresponding POCO entities and a Repository layer to access the database.
People: PersonId PK, Firsname, Lastname
FavoriteRestaurants: ID PK, PersonId, RestaurantId
Restaurants: ResaurantId PK, Name
If I have a PersonId, what is the best way to list all this person's favorite restaurant names?
Or how would I do to initialise this Enumerable based on the person's Id using a repository layer?
IEnumerable MyFavoriteRestaurants = ???
I know I could use foreach to loop on the Person.FavoriteRestaurants collections an retrieve each FavoriteRestaurant.Restaurant one by one, but I was wondering if there were a more elegant way to do this in one line of code.
UPDATE
Here is an example of a Person POCO entity class in my project. This code has been generated by a Microsoft template downloaded from here:
http://visualstudiogallery.msdn.microsoft.com/23df0450-5677-4926-96cc-173d02752313/
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
namespace UpDir.Domain
{
public partial class Person : EntityBase
{
#region Primitive Properties
public virtual int PersonId
{
get;
set;
}
public virtual string Firstname
{
get;
set;
}
public virtual string Middlename
{
get;
set;
}
public virtual string Lastname
{
get;
set;
}
public virtual string Nickname
{
get;
set;
}
public virtual string EncryptedEmail
{
get;
set;
}
public virtual string Photo
{
get;
set;
}
public virtual short StatusId
{
get { return _statusId; }
set
{
if (_statusId != value)
{
if (Status != null && Status.StatusId != value)
{
Status = null;
}
_statusId = value;
}
}
}
private short _statusId;
#endregion
#region Navigation Properties
public virtual ICollection<Member> Members
{
get
{
if (_members == null)
{
var newCollection = new FixupCollection<Member>();
newCollection.CollectionChanged += FixupMembers;
_members = newCollection;
}
return _members;
}
set
{
if (!ReferenceEquals(_members, value))
{
var previousValue = _members as FixupCollection<Member>;
if (previousValue != null)
{
previousValue.CollectionChanged -= FixupMembers;
}
_members = value;
var newValue = value as FixupCollection<Member>;
if (newValue != null)
{
newValue.CollectionChanged += FixupMembers;
}
}
}
}
private ICollection<Member> _members;
public virtual ICollection<Message> Messages
{
get
{
if (_messages == null)
{
var newCollection = new FixupCollection<Message>();
newCollection.CollectionChanged += FixupMessages;
_messages = newCollection;
}
return _messages;
}
set
{
if (!ReferenceEquals(_messages, value))
{
var previousValue = _messages as FixupCollection<Message>;
if (previousValue != null)
{
previousValue.CollectionChanged -= FixupMessages;
}
_messages = value;
var newValue = value as FixupCollection<Message>;
if (newValue != null)
{
newValue.CollectionChanged += FixupMessages;
}
}
}
}
private ICollection<Message> _messages;
public virtual ICollection<Notification> Notifications
{
get
{
if (_notifications == null)
{
var newCollection = new FixupCollection<Notification>();
newCollection.CollectionChanged += FixupNotifications;
_notifications = newCollection;
}
return _notifications;
}
set
{
if (!ReferenceEquals(_notifications, value))
{
var previousValue = _notifications as FixupCollection<Notification>;
if (previousValue != null)
{
previousValue.CollectionChanged -= FixupNotifications;
}
_notifications = value;
var newValue = value as FixupCollection<Notification>;
if (newValue != null)
{
newValue.CollectionChanged += FixupNotifications;
}
}
}
}
private ICollection<Notification> _notifications;
public virtual Status Status
{
get { return _status; }
set
{
if (!ReferenceEquals(_status, value))
{
var previousValue = _status;
_status = value;
FixupStatus(previousValue);
}
}
}
private Status _status;
public virtual ICollection<UpDirEmail> FromEmails
{
get
{
if (_fromEmails == null)
{
var newCollection = new FixupCollection<UpDirEmail>();
newCollection.CollectionChanged += FixupFromEmails;
_fromEmails = newCollection;
}
return _fromEmails;
}
set
{
if (!ReferenceEquals(_fromEmails, value))
{
var previousValue = _fromEmails as FixupCollection<UpDirEmail>;
if (previousValue != null)
{
previousValue.CollectionChanged -= FixupFromEmails;
}
_fromEmails = value;
var newValue = value as FixupCollection<UpDirEmail>;
if (newValue != null)
{
newValue.CollectionChanged += FixupFromEmails;
}
}
}
}
private ICollection<UpDirEmail> _fromEmails;
public virtual ICollection<UpDirEmail> ToEmails
{
get
{
if (_toEmails == null)
{
var newCollection = new FixupCollection<UpDirEmail>();
newCollection.CollectionChanged += FixupToEmails;
_toEmails = newCollection;
}
return _toEmails;
}
set
{
if (!ReferenceEquals(_toEmails, value))
{
var previousValue = _toEmails as FixupCollection<UpDirEmail>;
if (previousValue != null)
{
previousValue.CollectionChanged -= FixupToEmails;
}
_toEmails = value;
var newValue = value as FixupCollection<UpDirEmail>;
if (newValue != null)
{
newValue.CollectionChanged += FixupToEmails;
}
}
}
}
private ICollection<UpDirEmail> _toEmails;
public virtual ICollection<UpDirEvent> UpDirEvents
{
get
{
if (_upDirEvents == null)
{
var newCollection = new FixupCollection<UpDirEvent>();
newCollection.CollectionChanged += FixupUpDirEvents;
_upDirEvents = newCollection;
}
return _upDirEvents;
}
set
{
if (!ReferenceEquals(_upDirEvents, value))
{
var previousValue = _upDirEvents as FixupCollection<UpDirEvent>;
if (previousValue != null)
{
previousValue.CollectionChanged -= FixupUpDirEvents;
}
_upDirEvents = value;
var newValue = value as FixupCollection<UpDirEvent>;
if (newValue != null)
{
newValue.CollectionChanged += FixupUpDirEvents;
}
}
}
}
private ICollection<UpDirEvent> _upDirEvents;
#endregion
#region Association Fixup
private void FixupStatus(Status previousValue)
{
if (previousValue != null && previousValue.People.Contains(this))
{
previousValue.People.Remove(this);
}
if (Status != null)
{
if (!Status.People.Contains(this))
{
Status.People.Add(this);
}
if (StatusId != Status.StatusId)
{
StatusId = Status.StatusId;
}
}
}
private void FixupMembers(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
{
foreach (Member item in e.NewItems)
{
item.Person = this;
}
}
if (e.OldItems != null)
{
foreach (Member item in e.OldItems)
{
if (ReferenceEquals(item.Person, this))
{
item.Person = null;
}
}
}
}
private void FixupMessages(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
{
foreach (Message item in e.NewItems)
{
item.Person = this;
}
}
if (e.OldItems != null)
{
foreach (Message item in e.OldItems)
{
if (ReferenceEquals(item.Person, this))
{
item.Person = null;
}
}
}
}
private void FixupNotifications(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
{
foreach (Notification item in e.NewItems)
{
item.Person = this;
}
}
if (e.OldItems != null)
{
foreach (Notification item in e.OldItems)
{
if (ReferenceEquals(item.Person, this))
{
item.Person = null;
}
}
}
}
private void FixupFromEmails(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
{
foreach (UpDirEmail item in e.NewItems)
{
item.FromPerson = this;
}
}
if (e.OldItems != null)
{
foreach (UpDirEmail item in e.OldItems)
{
if (ReferenceEquals(item.FromPerson, this))
{
item.FromPerson = null;
}
}
}
}
private void FixupToEmails(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
{
foreach (UpDirEmail item in e.NewItems)
{
item.ToPerson = this;
}
}
if (e.OldItems != null)
{
foreach (UpDirEmail item in e.OldItems)
{
if (ReferenceEquals(item.ToPerson, this))
{
item.ToPerson = null;
}
}
}
}
private void FixupUpDirEvents(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
{
foreach (UpDirEvent item in e.NewItems)
{
item.Person = this;
}
}
if (e.OldItems != null)
{
foreach (UpDirEvent item in e.OldItems)
{
if (ReferenceEquals(item.Person, this))
{
item.Person = null;
}
}
}
}
#endregion
}
}

You don't need to think too much about that, EF will do it for you if you have defined your entity classes correct way like this,
Public class Person{
public int PersonId {get;set;}
public string Firsname{get;set;}
....
public virtual IList<Resturent> Resturents {get;set;}
}
Public class Restaurant{
public int ResaurantId {get;set;}
public string Name{get;set;}
....
public virtual IList<Resturent> People{get;set;}
}
Then you can simply access person.Restaurants to get all restaurants.

I finally figured it out. This is how I am doing it:
IEnumerable<Restaurants> MyFavoriteRestaurants = person.FavoriteRestaurants.Select(m => m.Restaurants);

Related

How to implement AdMob native ads in Xamarin Forms IOS?

I'm having a Xamarin Forms application where I could successfully add banner ads and native ads for the android with custom renderers using Google AdMob NuGet. What I'm trying to achieve here is to make them work on IOS, I managed to do that (I suppose as I'm receiving test ads) with banner but when it comes to native, I get unified native ad and it never renders...
I'm using it inside of a custom listview data template which I thought it might cause an issue, so I tried using it in the page itself but no luck, same issue.
Here is my IOS renderer so far:
[assembly: ExportRenderer(typeof(NativeAdMobUnit), typeof(NativeAdMobUnitRenderer))]
namespace Example.iOS.Components
{
public class NativeAdMobUnitRenderer : ViewRenderer<NativeAdMobUnit, NativeExpressAdView>
{
protected override void OnElementChanged(ElementChangedEventArgs<NativeAdMobUnit> e)
{
base.OnElementChanged(e);
if (e.NewElement == null)
return;
if (e.OldElement == null)
{
CreateAdView(this, e.NewElement.AdUnitId);
}
}
private void CreateAdView(NativeAdMobUnitRenderer renderer,String AdUnitId)
{
if (Element == null) return;
var loader = new AdLoader(
AdUnitId,
GetVisibleViewController(),
new AdLoaderAdType[] { AdLoaderAdType.UnifiedNative },
new AdLoaderOptions[] {
new NativeAdViewAdOptions {PreferredAdChoicesPosition = AdChoicesPosition.TopRightCorner}
});
var request = Request.GetDefaultRequest();
request.TestDevices = new string[] { Request.SimulatorId };
try
{
loader.Delegate = new MyAdLoaderDelegate(renderer);
Device.BeginInvokeOnMainThread(() => {
loader.LoadRequest(Request.GetDefaultRequest());
});
}
catch(Exception ex)
{
}
}
private UIViewController GetVisibleViewController()
{
var windows = UIApplication.SharedApplication.Windows;
foreach (var window in windows)
{
if (window.RootViewController != null)
{
return window.RootViewController;
}
}
return null;
}
private class MyAdLoaderDelegate : NSObject, IUnifiedNativeAdLoaderDelegate
{
private readonly NativeAdMobUnitRenderer _renderer;
public MyAdLoaderDelegate(NativeAdMobUnitRenderer renderer)
{
_renderer = renderer;
}
public void DidReceiveUnifiedNativeAd(AdLoader adLoader, UnifiedNativeAd nativeAd)
{
Debug.WriteLine("DidReceiveUnifiedNativeAd");
}
public void DidFailToReceiveAd(AdLoader adLoader, RequestError error)
{
Debug.WriteLine("DidFailToReceiveAd");
}
public void DidFinishLoading(AdLoader adLoader)
{
Debug.WriteLine("DidFinishLoading");
}
}
}
}
And that's the same but for Android which is working as expected:
[assembly: ExportRenderer(typeof(NativeAdMobUnit), typeof(NativeAdMobUnitRenderer))]
namespace Example.Droid.Renderers
{
public class NativeAdMobUnitRenderer : ViewRenderer
{
public NativeAdMobUnitRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.View> e)
{
base.OnElementChanged(e);
if (Control == null)
{
NativeAdMobUnit NativeAdUnit = (NativeAdMobUnit)Element;
var adLoader = new AdLoader.Builder(Context, NativeAdUnit.AdUnitId);
var listener = new UnifiedNativeAdLoadedListener();
listener.OnNativeAdLoaded += (s, ad) =>
{
try
{
var root = new UnifiedNativeAdView(Context);
var inflater = (LayoutInflater)Context.GetSystemService(Context.LayoutInflaterService);
var adView = (UnifiedNativeAdView)inflater.Inflate(Resource.Layout.ad_unified, root);
populateUnifiedNativeAdView(ad, adView);
SetNativeControl(adView);
}
catch
{
}
};
adLoader.ForUnifiedNativeAd(listener);
var requestBuilder = new AdRequest.Builder();
adLoader.Build().LoadAd(requestBuilder.Build());
}
}
private void populateUnifiedNativeAdView(UnifiedNativeAd nativeAd, UnifiedNativeAdView adView)
{
adView.MediaView = adView.FindViewById<MediaView>(Resource.Id.ad_media);
// Set other ad assets.
adView.HeadlineView = adView.FindViewById<TextView>(Resource.Id.ad_headline);
adView.BodyView = adView.FindViewById<TextView>(Resource.Id.ad_body);
adView.CallToActionView = adView.FindViewById<TextView>(Resource.Id.ad_call_to_action);
adView.IconView = adView.FindViewById<ImageView>(Resource.Id.ad_app_icon);
adView.PriceView = adView.FindViewById<TextView>(Resource.Id.ad_price);
adView.StarRatingView = adView.FindViewById<RatingBar>(Resource.Id.ad_stars);
adView.StoreView = adView.FindViewById<TextView>(Resource.Id.ad_store);
adView.AdvertiserView = adView.FindViewById<TextView>(Resource.Id.ad_advertiser);
// The headline and mediaContent are guaranteed to be in every UnifiedNativeAd.
((TextView)adView.HeadlineView).Text = nativeAd.Headline;
// These assets aren't guaranteed to be in every UnifiedNativeAd, so it's important to
// check before trying to display them.
if (nativeAd.Body == null)
{
adView.BodyView.Visibility = ViewStates.Invisible;
}
else
{
adView.BodyView.Visibility = ViewStates.Visible;
((TextView)adView.BodyView).Text = nativeAd.Body;
}
if (nativeAd.CallToAction == null)
{
adView.CallToActionView.Visibility = ViewStates.Invisible;
}
else
{
adView.CallToActionView.Visibility = ViewStates.Visible;
((Android.Widget.Button)adView.CallToActionView).Text = nativeAd.CallToAction;
}
if (nativeAd.Icon == null)
{
adView.IconView.Visibility = ViewStates.Gone;
}
else
{
((ImageView)adView.IconView).SetImageDrawable(nativeAd.Icon.Drawable);
adView.IconView.Visibility = ViewStates.Visible;
}
if (string.IsNullOrEmpty(nativeAd.Price))
{
adView.PriceView.Visibility = ViewStates.Gone;
}
else
{
adView.PriceView.Visibility = ViewStates.Visible;
((TextView)adView.PriceView).Text = nativeAd.Price;
}
if (nativeAd.Store == null)
{
adView.StoreView.Visibility = ViewStates.Invisible;
}
else
{
adView.StoreView.Visibility = ViewStates.Visible;
((TextView)adView.StoreView).Text = nativeAd.Store;
}
if (nativeAd.StarRating == null)
{
adView.StarRatingView.Visibility = ViewStates.Invisible;
}
else
{
((RatingBar)adView.StarRatingView).Rating = nativeAd.StarRating.FloatValue();
adView.StarRatingView.Visibility = ViewStates.Visible;
}
if (nativeAd.Advertiser == null)
{
adView.AdvertiserView.Visibility = ViewStates.Invisible;
}
else
{
((TextView)adView.AdvertiserView).Text = nativeAd.Advertiser;
adView.AdvertiserView.Visibility = ViewStates.Visible;
}
adView.SetNativeAd(nativeAd);
}
}
public class UnifiedNativeAdLoadedListener : AdListener, UnifiedNativeAd.IOnUnifiedNativeAdLoadedListener
{
public void OnUnifiedNativeAdLoaded(UnifiedNativeAd ad)
{
OnNativeAdLoaded?.Invoke(this, ad);
}
public EventHandler<UnifiedNativeAd> OnNativeAdLoaded { get; set; }
}
}

Issue with Xamarin Firebase Subscribe to a Child with no Key - Newtonsoft.Json error

I have a Firebase Child called "Parameters" that stores some data while my program runs. I populate it with "Put" and "Patch" actions. I cannot get the subscribe to work... I'm stuck on this Newtonsoft.Json.JsonSerializationException and I've tried several things but cannot figure it out. You can see in the error, I am getting the payload back... I just cannot parse it into my ViewParameterModel property variables. I would appreciate any help to get this working. Thanks, Brian
$exception {Firebase.Database.FirebaseException: Exception occured while processing the request.
Request Data: Response: {"aug":true,"fan":true,"ign":false,"mode":"Off","target":200}
---> Newtonsoft.Json.JsonSerializationException: Error converting value True to type 'Chart_sample.ViewParameterModel'. Path 'aug', line 1, position 11.
---> System.ArgumentException: Could not cast or convert from System.Boolean to Chart_sample.ViewParameterModel.
FirebaseHelper.cs
...
private readonly string ChildParams = "ControllerData/Pellet_Pirate_1/Parameters";
public ObservableCollection<Parameter> GetParameters()
{
firebase.Child(ChildParams).AsObservable<ViewParameterModel>().Subscribe(snapp =>
{
ViewParameterModel.aug = snapp.Object.aug;
ViewParameterModel.fan = snapp.Object.fan;
ViewParameterModel.ign = snapp.Object.ign;
ViewParameterModel.mode = snapp.Object.mode;
ViewParameterModel.target = snapp.Object.target;
});
return null;
}
...
ViewParameterModel.cs
public class ViewParameterModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private bool Fan = false;
public bool fan
{
get
{
return Fan;
}
set
{
if (Fan != value)
{
Fan = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("fan"));
}
}
}
private bool Igniter = false;
public bool ign
{
get
{
return Igniter;
}
set
{
if (Igniter != value)
{
Igniter = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("ign"));
}
}
}
private bool Auger = false;
public bool aug
{
get
{
return Auger;
}
set
{
if (Auger != value)
{
Auger = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("aug"));
}
}
}
private string Mode = "Off";
public string mode
{
get
{
return Mode;
}
set
{
if (Mode != value)
{
Mode = value;
Debug.WriteLine("Mode: " + Mode);
if (SegmentBindingContext != null)
{
SegmentBindingContext.index = Mode.Equals("Off") ? 0 : Mode.Equals("Start") ? 1 : Mode.Equals("Smoke") ? 2 :
Mode.Equals("Hold") ? 3 : Mode.Equals("Ignite") ? 4 : 5;
}
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("mode"));
}
}
}
private int Target = 0;
public int target
{
get
{
return Target;
}
set
{
if (Target != value)
{
Target = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("target"));
}
}
}
}
}

how to implement Android In App BillingClient in Xamarin.Android Asynchronously

I am trying to implement below java code in c# referring to Android documentation
List<String> skuList = new ArrayList<> ();
skuList.add("premium_upgrade");
skuList.add("gas");
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(SkuType.INAPP);
billingClient.querySkuDetailsAsync(params.build(),
new SkuDetailsResponseListener() {
#Override
public void onSkuDetailsResponse(BillingResult billingResult,
List<SkuDetails> skuDetailsList) {
// Process the result.
}
});
I have here 2 questions. I thought that i would run this code on a separate thread than UI thread like below to keep my ui responsive while network connection is done. is that the correct approach? QuerySkuDetailsAsync is called async but doesnt implement as async. how should this be working and how to handle in c# because it will fire and forget but Listener to handle the response.
public async Task<List<InAppBillingProduct>> GetProductsAsync(List<string> ProductIds)
{
var getSkuDetailsTask = Task.Factory.StartNew(() =>
{
var prms = SkuDetailsParams.NewBuilder();
var type = BillingClient.SkuType.Inapp;
prms.SetSkusList(ProductIds).SetType(type);
BillingClient.QuerySkuDetailsAsync(prms.Build(), new SkuDetailsResponseListener());
return InAppBillingProducts;
});
return await getSkuDetailsTask;
}
2nd question regarding how to handle with the listener as below. How do I return value from the listener. I need return list of InAppBillingProduct object.
public class SkuDetailsResponseListener : Java.Lang.Object, ISkuDetailsResponseListener
{
public void OnSkuDetailsResponse(BillingResult billingResult, IList<SkuDetails> skus)
{
if (billingResult.ResponseCode == BillingResponseCode.Ok)
{
// get list of Products here and return
}
}
}
FYI. This is how I did it. This is not a complete code but this will give you and idea.
Listener - PCL
============
private async Task EventClicked()
{
var skuList = new List<string>();
skuList.Add("[nameofsubscriptionfoundinyourgoogleplay]");
if (await _billingClientLifecycle.Initialize(skuList, DisconnectedConnection))
{
var firstProduct = _billingClientLifecycle?.ProductsInStore?.FirstOrDefault();
if (firstProduct != null)
{
//purchase here
}
}
}
private void DisconnectedConnection()
{
//Todo.alfon. handle disconnection here...
}
Interface - PCL
===========
public interface IInAppBillingMigratedNew
{
List<InAppBillingPurchase> PurchasedProducts { get; set; }
List<InAppBillingProduct> ProductsInStore { get; set; }
Task<bool> Initialize(List<String> skuList, Action onDisconnected = null);
}
Dependency - Platform Droid
===============
[assembly: XF.Dependency(typeof(InAppBillingMigratedNew))]
public class InAppBillingMigratedNew : Java.Lang.Object, IBillingClientStateListener
, ISkuDetailsResponseListener, IInAppBillingMigratedNew
{
private Activity Context => CrossCurrentActivity.Current.Activity
?? throw new NullReferenceException("Current Context/Activity is null");
private BillingClient _billingClient;
private List<string> _skuList = new List<string>();
private TaskCompletionSource<bool> _tcsInitialized;
private Action _disconnectedAction;
private Dictionary<string, SkuDetails> _skusWithSkuDetails = new Dictionary<string, SkuDetails>();
public List<InAppBillingPurchase> PurchasedProducts { get; set; }
public List<InAppBillingProduct> ProductsInStore { get; set; }
public IntPtr Handle => throw new NotImplementedException();
public Task<bool> Initialize(List<string> skuList, Action disconnectedAction = null)
{
_disconnectedAction = disconnectedAction;
_tcsInitialized = new TaskCompletionSource<bool>();
var taskInit = _tcsInitialized.Task;
_skuList = skuList;
_billingClient = BillingClient.NewBuilder(Context)
.SetListener(this)
.EnablePendingPurchases()
.Build();
if (!_billingClient.IsReady)
{
_billingClient.StartConnection(this);
}
return taskInit;
}
#region IBillingClientStateListener
public void OnBillingServiceDisconnected()
{
Console.WriteLine($"Connection disconnected.");
_tcsInitialized?.TrySetResult(false);
_disconnectedAction?.Invoke();
}
public void OnBillingSetupFinished(BillingResult billingResult)
{
var responseCode = billingResult.ResponseCode;
var debugMessage = billingResult.DebugMessage;
if (responseCode == BillingResponseCode.Ok)
{
QuerySkuDetails();
QueryPurchases();
_tcsInitialized?.TrySetResult(true);
}
else
{
Console.WriteLine($"Failed connection {debugMessage}");
_tcsInitialized?.TrySetResult(false);
}
}
#endregion
#region ISkuDetailsResponseListener
public void OnSkuDetailsResponse(BillingResult billingResult, IList<SkuDetails> skuDetailsList)
{
if (billingResult == null)
{
Console.WriteLine("onSkuDetailsResponse: null BillingResult");
return;
}
var responseCode = billingResult.ResponseCode;
var debugMessage = billingResult.DebugMessage;
switch (responseCode)
{
case BillingResponseCode.Ok:
if (skuDetailsList == null)
{
_skusWithSkuDetails.Clear();
}
else
{
if (skuDetailsList.Count > 0)
{
ProductsInStore = new List<InAppBillingProduct>();
}
foreach (var skuDetails in skuDetailsList)
{
_skusWithSkuDetails.Add(skuDetails.Sku, skuDetails);
//ToDo.alfon. make use mapper here
ProductsInStore.Add(new InAppBillingProduct
{
Name = skuDetails.Title,
Description = skuDetails.Description,
ProductId = skuDetails.Sku,
CurrencyCode = skuDetails.PriceCurrencyCode,
LocalizedIntroductoryPrice = skuDetails.IntroductoryPrice,
LocalizedPrice = skuDetails.Price,
MicrosIntroductoryPrice = skuDetails.IntroductoryPriceAmountMicros,
MicrosPrice = skuDetails.PriceAmountMicros
});
}
}
break;
case BillingResponseCode.ServiceDisconnected:
case BillingResponseCode.ServiceUnavailable:
case BillingResponseCode.BillingUnavailable:
case BillingResponseCode.ItemUnavailable:
case BillingResponseCode.DeveloperError:
case BillingResponseCode.Error:
Console.WriteLine("onSkuDetailsResponse: " + responseCode + " " + debugMessage);
break;
case BillingResponseCode.UserCancelled:
Console.WriteLine("onSkuDetailsResponse: " + responseCode + " " + debugMessage);
break;
// These response codes are not expected.
case BillingResponseCode.FeatureNotSupported:
case BillingResponseCode.ItemAlreadyOwned:
case BillingResponseCode.ItemNotOwned:
default:
Console.WriteLine("onSkuDetailsResponse: " + responseCode + " " + debugMessage);
break;
}
}
#endregion
#region Helper Methods Private
private void ProcessPurchases(List<Purchase> purchasesList)
{
if (purchasesList == null)
{
Console.WriteLine("No purchases done.");
return;
}
if (IsUnchangedPurchaseList(purchasesList))
{
Console.WriteLine("Purchases has not changed.");
return;
}
_purchases.AddRange(purchasesList);
PurchasedProducts = _purchases.Select(sku => new InAppBillingPurchase
{
PurchaseToken = sku.PurchaseToken
})?.ToList();
if (purchasesList != null)
{
LogAcknowledgementStatus(purchasesList);
}
}
private bool IsUnchangedPurchaseList(List<Purchase> purchasesList)
{
// TODO: Optimize to avoid updates with identical data.
return false;
}
private void LogAcknowledgementStatus(List<Purchase> purchasesList)
{
int ack_yes = 0;
int ack_no = 0;
foreach (var purchase in purchasesList)
{
if (purchase.IsAcknowledged)
{
ack_yes++;
}
else
{
ack_no++;
}
}
//Log.d(TAG, "logAcknowledgementStatus: acknowledged=" + ack_yes +
// " unacknowledged=" + ack_no);
}
private void QuerySkuDetails()
{
var parameters = SkuDetailsParams
.NewBuilder()
.SetType(BillingClient.SkuType.Subs)
.SetSkusList(_skuList)
.Build();
_billingClient.QuerySkuDetailsAsync(parameters, this);
}
private void QueryPurchases()
{
if (!_billingClient.IsReady)
{
Console.WriteLine("queryPurchases: BillingClient is not ready");
}
var result = _billingClient.QueryPurchases(BillingClient.SkuType.Subs);
ProcessPurchases(result?.PurchasesList?.ToList());
}
#endregion
}

LINQ PredicateBuilder not work in my dynamic search

I have a book table in my database and I have book view named vwShared in my edmx. I want to create dynamic search with operators for user to find books. I have 2 SearchColumns dropdownlist contains "Title, Authors, Published Year, Subject". I have 2 SearchType dropdownlist contains "StartsWith, Contains, EndsWith, Equals". I have another dropdownlist contains "AND, OR" to combine 2 search results. The following is my code.
var predicate = PredicateBuilder.True<DataLayer.vwShared>();
if (joinOperator == "AND")
{
if (SearchColumn1 == "Title" && SearchType1 == "Contains")
predicate = predicate.And(e1 => e1.Title.Contains(txtSearch1.Text));
if (SearchColumn2 == "Authors" && SearchType2 == "Contains")
predicate = predicate.And(e1 => e1.Authors.Contains(txtSearch2.Text));
}
else if (joinOperator == "OR")
{
if (SearchColumn1 == "Title" && SearchType1 == "Contains")
predicate = predicate.Or(e1 => e1.Title.Contains(txtSearch1.Text));
if (SearchColumn2 == "Authors" && SearchType2 == "Contains")
predicate = predicate.Or(e1 => e1.Authors.Contains(txtSearch2.Text));
}
List<DataLayer.vwShared> bookList= new DataLayer.Solib_DMREntities().SP_SharedData_GetAll("AllLocal").ToList<DataLayer.vwShared>();
var bookList= from books in bookList.AsQueryable().Where(predicate)
select books ;
gvBooks.DataSource = bookList.ToList();
gvBooks.DataBind();
The above code not return proper results. Is there something wrong. ?
The following is my references website.
http://www.albahari.com/nutshell/predicatebuilder.aspx
Please give me advice.
Thanks.
Answering your concrete question. The problem is in the branch for building OR predicate, in which case you should start with PredicateBuilder.False, otherwice there will not be filtering at all (as we know from the school, true or something is always true :)
// ...
else if (joinOperator == "OR")
{
predicate = PredicateBuilder.False<DataLayer.vwShared>();
// ...
}
// ...
step 1:Model
public class Person
{
public int PersonId { get; set; }
public int? Age { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int? Salary { get; set; }
}
public class PersonDBContext : DbContext
{
public virtual DbSet<Person> People { get; set; }
}
step 2 : controller
public class PersonController
{
PersonDBContext db = new PersonDBContext();
public void Add(Person person)
{
db.People.Add(person);
db.SaveChanges();
}
public List<Person> GetAll()
{
return db.People.ToList();
}
public List<Person> GetByPredicateValue(Expression<Func<Person, bool>> predicate)
{
if (predicate != null)
return db.People.Where(predicate.Compile()).ToList();
else
return null;
}
public List<Person> GetByPredicateAndPersonListValue(List<Person> PeopleList,Expression<Func<Person, bool>> predicate)
{
if (predicate != null)
return PeopleList.Where(predicate.Compile()).ToList();
else
return null;
}
}
step 3: code behind
public partial class MainWindow : Window
{
PersonController pc;
public static List<Person> PeopleFilterList = null;
public static string CurrentColumn = null;
public MainWindow()
{
pc = new PersonController();
InitializeComponent();
grid.ItemsSource = pc.GetAll();
grid.PreviewMouseDown += grid_PreviewMouseDown;
}
void grid_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
TableViewHitInfo hi = ((TableView)grid.View).CalcHitInfo(e.OriginalSource as DependencyObject);
if (hi == null) return;
if (hi.HitTest == TableViewHitTest.ColumnHeader || hi.HitTest == TableViewHitTest.ColumnHeaderFilterButton)
{
grid.UnselectAll();
GridColumn currentColumn = ((DevExpress.Xpf.Grid.GridViewHitInfoBase)(hi)).Column;
CurrentColumn = currentColumn.FieldName;
(grid.View as TableView).SelectCells(0, currentColumn, grid.VisibleRowCount - 1, currentColumn);
}
}
Expression<Func<Person, bool>> _result=null;
string str="";
private void IdForm_ButtonClicked(object sender, IdentityUpdateEventArgs e)
{
_result = e.FirstName;
}
public MainWindow(Expression<Func<Person, bool>> result)
{
Window1 f = new Window1();
f.IdentityUpdated += new Window1.IdentityUpdateHandler(IdForm_ButtonClicked);
pc = new PersonController();
InitializeComponent();
_result = result;
if (PeopleFilterList != null)
PeopleFilterList = pc.GetByPredicateAndPersonListValue(PeopleFilterList,_result).ToList();
else
PeopleFilterList = pc.GetByPredicateValue(_result).ToList();
grid.ItemsSource = PeopleFilterList;
grid.PreviewMouseDown += grid_PreviewMouseDown;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Window1 w1 = new Window1(CurrentColumn);
w1.Show();
}
}
step 4 : Filter code behind
public partial class Window1 : Window
{
public delegate void IdentityUpdateHandler(object sender, IdentityUpdateEventArgs e);
public event IdentityUpdateHandler IdentityUpdated;
string _currentColumn = null;
public Window1()
{
InitializeComponent();
}
public Window1(string currentColumn)
{
_currentColumn = currentColumn;
InitializeComponent();
}
public static Expression<Func<Person, bool>> predicateValue;
IdentityUpdateEventArgs args;
private void Button_Click(object sender, RoutedEventArgs e)
{
string operatorName = "";
if (!String.IsNullOrEmpty(txtSmaller.Text.Trim()))
operatorName = txtSmaller.Name;
else if (!String.IsNullOrEmpty(txtElder.Text.Trim()))
operatorName = txtElder.Name;
else if (!String.IsNullOrEmpty(txtContains.Text.Trim()))
operatorName = txtContains.Name;
else if (!String.IsNullOrEmpty(txtStartWith.Text.Trim()))
operatorName = txtStartWith.Name;
else if (!String.IsNullOrEmpty(txtEqual.Text.Trim()))
operatorName = txtEqual.Name;
else if (!String.IsNullOrEmpty(txtNotEqual.Text.Trim()))
operatorName = txtNotEqual.Name;
else if (!String.IsNullOrEmpty(txtSmallerOrEqual.Text.Trim()))
operatorName = txtSmallerOrEqual.Name;
else if (!String.IsNullOrEmpty(txtElderOrEqual.Text.Trim()))
operatorName = txtElderOrEqual.Name;
else if (!String.IsNullOrEmpty(txtSmallerThan.Text.Trim()) && !String.IsNullOrEmpty(txtBiggerThan.Text.Trim()))
operatorName = txtSmallerThan.Name;
switch (operatorName)
{
case "txtSmaller":
predicateValue = (x => (int)x.GetType().GetProperty(_currentColumn).GetValue(x, null) < Convert.ToInt32(txtSmaller.Text));
break;
case "txtElder":
predicateValue = (x => (int)x.GetType().GetProperty(_currentColumn).GetValue(x, null) > Convert.ToInt32(txtElder.Text));
break;
case "txtSmallerOrEqual":
predicateValue = (x => (int)x.GetType().GetProperty(_currentColumn).GetValue(x, null) <= Convert.ToInt32(txtSmallerOrEqual.Text));
break;
case "txtElderOrEqual":
predicateValue = (x => (int)x.GetType().GetProperty(_currentColumn).GetValue(x, null) >= Convert.ToInt32(txtElderOrEqual.Text));
break;
case "txtEqual":
predicateValue = (x => (int)x.GetType().GetProperty(_currentColumn).GetValue(x, null) == Convert.ToInt32(txtEqual.Text));
break;
case "txtNotEqual":
predicateValue = (x => (int)x.GetType().GetProperty(_currentColumn).GetValue(x, null) != Convert.ToInt32(txtNotEqual.Text));
break;
case "txtSmallerThan":
predicateValue = (x => (int)x.GetType().GetProperty(_currentColumn).GetValue(x, null) >= Convert.ToInt32(txtBiggerThan.Text)
&& (int)x.GetType().GetProperty(_currentColumn).GetValue(x, null) <= Convert.ToInt32(txtSmallerThan.Text));
break;
case "txtStartWith":
predicateValue = (x => x.GetType().GetProperty(_currentColumn).GetValue(x, null).ToString().StartsWith(txtStartWith.Text));
break;
case "txtContains":
predicateValue = (x => x.GetType().GetProperty(_currentColumn).GetValue(x,null).ToString().Contains(txtContains.Text));
break;
}
MainWindow mw = new MainWindow(predicateValue);
mw.Show();
this.Close();
}
void Window1_IdentityUpdated(object sender, IdentityUpdateEventArgs e)
{
e = args;
}
}
public class IdentityUpdateEventArgs : System.EventArgs
{
private Expression<Func<Person, bool>> mFirstName;
public IdentityUpdateEventArgs(Expression<Func<Person, bool>> sFirstName)
{
this.mFirstName = sFirstName;
}
public Expression<Func<Person, bool>> FirstName
{
get
{
return mFirstName;
}
}
}

Silverlight 5 validation issue

i'm trying to validate the data entry of my project using the validation in silverlight
this is the result
http://imageshack.us/photo/my-images/842/immagineleb.png/
as you can see the borders of almost all the textboxes are red, actually, in this case, no one of them should be red! And in all of the tooltips there's the same message.
there are the properties of the object that i use in the data context of the form
private int matricola;
public int Matricola
{
get { return matricola; }
set
{
ValidateRequiredInt("Matricola", value, "Inserire un numero");
matricola = value;
OnNotifyPropertyChanged("Matricola");
}
}
private String cognome;
public String Cognome
{
get { return cognome; }
set
{
ValidateRequiredString("Cognome", value, "Inserire cognome");
cognome = value;
OnNotifyPropertyChanged("Cognome");
}
}
private String nome;
public String Nome
{
get { return nome; }
set
{
ValidateRequiredString("Nome", value, "Inserire nome");
nome = value;
OnNotifyPropertyChanged("Nome");
}
}
private String codiceUtente;
public String CodiceUtente
{
get { return codiceUtente; }
set
{
ValidateRequiredString("CodiceUtente", value, "Inserire codice utente");
codiceUtente = value;
OnNotifyPropertyChanged("CodiceUtente");
}
}
private String password;
public String Password
{
get { return password; }
set
{
ValidateRequiredString("Password", value, "Inserire password");
password = value;
OnNotifyPropertyChanged("Password");
}
}
private int? idOrario;
public int? IdOrario
{
get { return idOrario; }
set { idOrario = value; }
}
private DateTime? dataAssunzione;
public DateTime? DataAssunzione
{
get { return dataAssunzione; }
set
{
if (value != null)
{
ValidateDateTime("DataAssunzione", (DateTime)value, "Immettere una data corretta");
if (((DateTime)value).Year == 1 && ((DateTime)value).Month == 1 && ((DateTime)value).Day == 1)
{
dataAssunzione = null;
}
else
{
dataAssunzione = value;
}
OnNotifyPropertyChanged("DataAssunzione");
}
else
{
dataAssunzione = null;
}
}
}
private DateTime? dataLicenziamento;
public DateTime? DataLicenziamento
{
get { return dataLicenziamento; }
set
{
if (value != null)
{
ValidateDateTime("DataLicenziamento", (DateTime)value, "Immettere una data corretta");
if (((DateTime)value).Year == 1 && ((DateTime)value).Month == 1 && ((DateTime)value).Day == 1)
{
dataLicenziamento = null;
}
else
{
dataLicenziamento = value;
}
OnNotifyPropertyChanged("DataLicenziamento");
}
else
{
dataLicenziamento = null;
}
}
}
private int idGruppoAnag;
public int IdGruppoAnag
{
get { return idGruppoAnag; }
set { idGruppoAnag = value; }
}
private int? costoOrario;
public int? CostoOrario
{
get { return costoOrario; }
set
{
if (value != null)
{
ValidateInt("CostoOrario", (int)value, "Immettere un numero o lasciare il campo vuoto");
if (value == 0 || value == -1)
{
costoOrario = null;
}
else
{
costoOrario = value;
}
OnNotifyPropertyChanged("CostoOrario");
}
else
{
costoOrario = null;
}
}
}
and these are the methods used for the validation
protected bool ValidateRequiredInt(string propName, int value, string errorText)
{
if (DataErrors.ContainsKey(propName))
{
DataErrors[propName].Remove(errorText);
}
if (value == 0 || value == -1)
{
AddError(propName, errorText);
return false;
}
OnErrorsChanged(propName);
return true;
}
//validazione dei campi che richiedono numeri interi nullable
protected bool ValidateInt(string propName, int value, string errorText)
{
if (DataErrors.ContainsKey(propName))
{
DataErrors[propName].Remove(errorText);
}
if (value == 0)
{
AddError(propName, errorText);
return false;
}
OnErrorsChanged(propName);
return true;
}
//validazione dei campi che richiedono stringhe
protected bool ValidateRequiredString(string propName, string value, string errorText)
{
//Clear any existing errors since we're revalidating now
if (DataErrors.ContainsKey(propName))
{
DataErrors[propName].Remove(errorText);
}
if (string.IsNullOrEmpty(value))
{
AddError(propName, errorText);
return false;
}
OnErrorsChanged(propName);
return true;
}
protected bool ValidateDateTime(string propName, DateTime value, string errorText)
{
//Clear any existing errors since we're revalidating now
if (DataErrors.ContainsKey(propName))
{
DataErrors[propName].Remove(errorText);
}
if (value.Year == 9999 && value.Month == 12 && value.Day == 31)
{
AddError(propName, errorText);
return false;
}
OnErrorsChanged(propName);
return true;
}
i'm also using using a dataconverter, in the two "Data" textboxes, and numberconverter, in the matricola and costo textboxes, as locals resources and i can say that they work fine.
i'm missing something?
How about implementing INotifyDataErrorInfo?
In a view-model base class:
public abstract class BaseViewModel : INotifyPropertyChanged, INotifyDataErrorInfo
{
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
#region INotifyDataErrorInfo Members
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
public System.Collections.IEnumerable GetErrors(string propertyName)
{
....
}
public System.Collections.IEnumerable GetErrors()
{
...
}
//Plus methods to push errors into an underlying error dictionary used by the above error get methods
}
Expand on this and you will have reusable base class for all view-models.
Validate properties in the appropriate setters. If they fail validation then push an error into the error dictionary keyed by property name. If validation succeeds then remove the validation error (if any) from the the dictionary for the property.
You will need to fire the ErrorsChanged event when you change the dictionary, but this can be achieved by having a protected
SetErrorForProperty(string propName, object error)
method whcih wraps this up.
Clearing an error can be done by passing null to this method and/or by having a separate
ClearErrorsFroProperty(string propName)
method.

Resources