If you had ever worked with RIA , you will come across a situation that you might want to load many entities from the server using different queries, before you can present an appropriate UI to your customer.
for example, customer, you might want to load customer detail infomation, customer history, customer order etc etc.
I did some search , and didn't find an appropriate batch loader, so create one by myself, in case someone else also need to implement similar features, can take it as a reference.
using System; using System.Collections.Generic; using System.Linq; using System.ServiceModel.DomainServices.Client; namespace SilverlightApplication4 { public class DomainContextBatchLoader { public abstract class LoadStep { public bool IsComplete { get; set; } public abstract void Execute(); public Action<LoadOperation> OnSuccess; public Action<LoadOperation> OnFail; } public class BatchLoadStep<T> : LoadStep where T : Entity { private DomainContext _context; public EntityQuery<T> EntityQuery { get; set; } private LoadBehavior _loadBehavior = LoadBehavior.MergeIntoCurrent; #region Construction public BatchLoadStep(DomainContext context, EntityQuery<T> query, LoadBehavior loadBehavior = LoadBehavior.MergeIntoCurrent) { _context = context; EntityQuery = query; _loadBehavior = loadBehavior; } #endregion #region Overrides public override void Execute() { _context.Load(EntityQuery, _loadBehavior, lp => { this.IsComplete = true; this.LoadOperation = lp; if (lp.IsComplete && !lp.HasError) { if (this.OnSuccess != null) { this.OnSuccess(lp); } } else { if (this.OnFail != null) { this.OnFail(lp); } } }, null); } #endregion public LoadOperation<T> LoadOperation { get; set; } } #region Construction public DomainContextBatchLoader(Action<DomainContextBatchLoader> completeAction) { this._completeAction = completeAction; } #endregion #region Private Properties private Action<DomainContextBatchLoader> _completeAction = null; private List<LoadStep> _lstSteps = new List<LoadStep>(); private List<LoadOperation> _lstFaildOperation = new List<LoadOperation>(); public event EventHandler OnComplete; #endregion #region Methods public void Add<T>(DomainContext context, EntityQuery<T> query, LoadBehavior loadBehavior) where T : Entity { var step = new BatchLoadStep<T>(context, query, loadBehavior); step.OnSuccess = lp => { this.CheckComplete(); }; step.OnFail = lp => { this._lstFaildOperation.Add(lp); this.CheckComplete(); }; _lstSteps.Add(step); } private void CheckComplete() { if (!this._lstSteps.Any(o => o.IsComplete == false)) { if (this._completeAction != null) { this._completeAction(this); } if (this.OnComplete != null) { this.OnComplete(this, new EventArgs()); } } } public void Start() { if (_lstSteps.Count > 0) _lstSteps.ForEach(o => o.Execute()); else { CheckComplete(); } } public IEnumerable<T> GetEntities<T>() where T : Entity { var step = _lstSteps.OfType<BatchLoadStep<T>>().FirstOrDefault(); if (step != null) return step.LoadOperation.Entities.OfType<T>(); return null; } public int FailedOperationCount { get { return _lstFaildOperation.Count; } } public IEnumerable<LoadOperation> FailedOperations { get { return _lstFaildOperation; } } #endregion } }
No comments:
Post a Comment