IAsyncRepository or IObservableRepository for silverlight 4 + WCF Data Services

后端 未结 2 695
忘了有多久
忘了有多久 2021-02-06 16:40

Update 2 : @Enigmativity has a brilliant answer. I\'ve implemented this into a IObservableRepository. Details in my answer below.


相关标签:
2条回答
  • 2021-02-06 16:50

    Just a quick, off the cuff answer.

    How about using the Reactive Extensions for .NET (Rx)?

    You could then define your repository as:

    public interface IObservableRepository<T> where T : class
    {
        IObservable<T> GetById(int id);
        IObservable<T> GetAll(Func<IQueryable<T>, IQueryable<T>> query);
        IObservable<Unit> InsertOnSubmit(T entity);
        IObservable<Unit> DeleteOnSubmit(T entity);
        IObservable<int> SubmitChanges();
    }
    

    All of the returned observables would contain single values, except for GetAll which would have zero or more.

    The Unit type is void in the Rx world. It's just a way of not needing to define a non-generic IObservable interface.

    You would then query like so:

    IObservableRepository<Foo> repo = ...;
    
    var foos = repo.GetAll(ts => ts.Where(t => t.Bar == "Hello"));
    
    foos.Subscribe(foo =>
    {
        // Do something asynchronously with each `Foo`.
    });
    

    And submit could be done like this:

    var submit =
        foos
            .Select(foo => repo.InsertOnSubmit(foo)).ToArray()
            .Select(s => repo.SubmitChanges());
    
    submit.Subscribe(result =>
    {
        // handle the asynchronous result of submit.
    });
    

    This is all based on trying to keep the repository methods as close as possible to the original, but it may be worth refactoring on the Silverlight side to something like this:

    public interface IObservableRepository<T> where T : class
    {
        IObservable<T> GetById(int id);
        IObservable<T[]> GetAll(Func<IQueryable<T>, IQueryable<T>> query);
        IObservable<int> Submit(T[] insertsOrUpdates);
        IObservable<int> Submit(T[] insertsOrUpdates, T[] deletes);
    }
    

    Submit would be a bit nicer now:

    repo.Submit(foos).Subscribe(result =>
    {
        // Handle asynchronous result of submit;
    });
    

    Like I said, off the cuff. :-)

    0 讨论(0)
  • 2021-02-06 16:52

    Too long to update the question, so I posted as an answer.

    So I implemented it like this:

    public interface IObservableRepository<T, TContext>
    {
        IObservable<T> GetById(int id);
        IObservable<IList<T>> GetAll(Func<TContext, IQueryable<T>> funcquery);
        IObservable<int[]> SubmitInserts(IList<T> inserts);
        IObservable<int[]> SubmitDeletes(IList<T> deletes);
        IObservable<int[]> SubmitUpdates(IList<T> updates);
        //helpers
        IObservable<int> SubmitInsert(T entity);
        IObservable<int> SubmitDelete(T entity);
        IObservable<int> SubmitUpdate(T entity);
    }
    

    Some notes :

    • TContext is needed for GetAll(), the implementation will have the Entity Framework DataServiceContext which will allow you to do the following:

      var foos = repo.GetAll(ts => ts.Where(t => t.Bar == "Hello"));
      //ts is a DataContext passed here by GetAll();
      
    • The methods marked //helpers just call the other methods that take arrays.
    • The actual return type for CRUD functions for WCF Data Services+Entity Framework is a DataServiceResponse. What I do is loop through them and return the Http Status Codes. So the ints returned for the CRUD methods are Http Status Codes.
    • When loading child entities I just eager loaded them by doing this:

      context.Products.Expand("Child").Expand("Child2");
      

    I can basically use it like this:

    productRepo.GetById(3).Subscribe(x => /* Do something with product x*/ );
    productRepo.SubmitUpdate(product)
             .Subscribe(r => /*return code should be 204 (http) 201 for insert */);
    //same for insert and delete
    

    Do tell me if I should put up the actual implementation here.

    Any comments on this would be well taken =)

    Thanks

    0 讨论(0)
提交回复
热议问题