-1

i'm really having a hard time deciding how to build my sql layer. i'm building a webservice that will communicate with both sql and No-SQL servers. So i came up with a bunch of ideas so that we can implemented testing, etc. etc.

Now i have bunch of files and a structure, i explain (Sorry i've i used names of patrons that i don't use... please correct me in that case): -IDatabaseStore.cs -SqlDatabaseStore.cs -NoSQLDatabaseStore.cs -and all my specific stores(like userStore.cs that implements the sql store for example).

And i wanted to do the following: Both SQL- and NoSQLDatabaseStore will implement the IDatabaseStore. These 2 classes will be abstract to provide the basic functionalities like the Repository pattern does. And all specific store will implement one of both abstract classes to not rebuild everything.

Now the problem: The No-SQL library that i use is MyCouch and is completly async, but for SQL i use L2SQL which isn't async.

Now my question: how is it preferred to set this up, in your opinion?

  1. Like example 1, forcing that both use async methods, also if they aren't async(like L2SQL).

  2. Make the interface like example 2, all dynamic an pass the generic type as Task in case that it needs to be Async. This way i don't obligate my interface nor abstract classes to be async (But void methods aren't async ever that case?).

  3. Did i missed a way to make L2SQL async? Notice: I've seen a lot of posts already, but they don't seem to fit in this model.

  4. Any other suggestions?

In case of performance i really would love tho have an Async L2SQL, because i will need to manage a lot of connections and this could really benifit the webservice. But for example a solution like: https://stackoverflow.com/a/252426/1364241 isn't awaitable, no?

Example 1:

public interface IDatabaseStore {
   Task<T> GetByID(string id);
   Task<List<T>> GetAll();
   Task Delete(T model);
   Task Update(T model);
   Task Insert(T model);
}

Example 2:

public interface IDatabaseStore {
    T GetByID(string id);
    List<T> GetAll();
    void Delete(T model);
    void Update(T model);
    void Insert(T model);
}
Community
  • 1
  • 1
Spons
  • 1,593
  • 1
  • 17
  • 46
  • Have you considered Entity Framework as a replacement for L2SQL? – Stephen Cleary Feb 10 '14 at 15:04
  • @StephenCleary yes i have been looking at it, but what i understood from round about 10 SO articles, is that L2SQL is faster then EF. Or is it in this case that the advantage of EF is bigger due to async methods? – Spons Feb 10 '14 at 15:06
  • @StephenCleary in that case it would be the perfect solution. – Spons Feb 10 '14 at 15:11
  • Yes, the latest version of EF supports `async`, and that would be the option I would choose. L2SQL has not been updated and probably won't be (it was originally an early version of EF that has been outdated for some time now ever since EF got feature parity with it). – Stephen Cleary Feb 10 '14 at 15:15
  • Thanks for that anwser @StephenCleary, i didn't knew that L2SQL was outdated, and certainly made the wrong choice on that point for the future of the project. I'll take a look to find some more information about it. Please give it as an awnser and i will accept. – Spons Feb 10 '14 at 15:18

2 Answers2

2

The latest version of Entity Framework supports asynchronous operations, so I recommend you use the asynchronous interface with EF6 and MyCouch implementations.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
0

This is discussed in depth in the article: Should I expose asynchronous wrappers for synchronous methods?

To summarize, no, you shouldn't. The best solution is to simply separate out what is synchronous from what is asynchronous. Have separate interfaces for each, have each implementation only implement the interface that corresponds to whether they are actually synchronous or asynchronous. Don't try to unify the two into a single interface.

What you have are two radically different types of DB operations. They are so different that they ought to be consumed differently. It's not correct for them to be interchangeable, so you shouldn't try to force that interchangeability.

Servy
  • 202,030
  • 26
  • 332
  • 449
  • Thanks for the article i will take a look at it. I agree that it are 2 radically different types of Database. But i don't agree that they aren't interchangeable. If i ask NoSQL to get me user X i need a getByID method. But when i ask it to SQL i want the exacte same method. Only with a different Execution. For that case this interface does server very well in my opinion. Besides by using L2SQL and MyCouch they can achieve a default implementation for such a simple method, which can prevent coding something mulitple times. – Spons Feb 10 '14 at 15:10
  • 1
    @spons If you already knew the answer to your question, and aren't willing to entertain other possible answers, then why ask the question in the first place? – Servy Feb 10 '14 at 15:11
  • i indeed am willing to look to other possible solutions. Look the comments on the main post. Though, i simply disagree with you on what you said. If i said something that isn't true please explain. I would love to accept your anwser if it's the right one, i only said i disagree and for what reason. I wasn't trying to offend you.... – Spons Feb 10 '14 at 15:16
  • @spons If all of your DB operations aren't actually asynchronous you shouldn't *pretend* that they're asynchronous. Generally that is going to be the "base" of the asynchrony of any application. If it's not actually asynchronous you probably should have the entire application not be asynchronous. If it needs to be, then it should *know* that the underlying UI isn't asynchronous and that it's offloading synchronous UI work to another thread, and do so explicitly. Otherwise it gives the false impression that your application is actually asynchronous when it's not. – Servy Feb 10 '14 at 15:20
  • I agree on that with you and i didn't want to pretend that they are async, that was the reason i asked the question here in the first place. But you're saying that my example at first wasn't good but if i use like suggested by @StephanCleary the Enity Framework which does work Async. In this case all my database operations would be async no? And then i would use the good approach no? And would give the good impression no? (Or did i misunderstood something?) – Spons Feb 10 '14 at 15:30
  • @spons If your DB operations are actually asynchronous, and you're not pretending that synchronous operations are asynchronous, then yes, you're doing it correctly. Forcing asynchronous operations to match a synchronous API (by synchronously waiting on all asynchronous operations) is just as bad. The whole point of the answer is that asynchronous operations should be exposed through asynchronous APIs, and synchronous operations should be exposed through synchronous APIs. – Servy Feb 10 '14 at 15:34