UnitOfWork, removing abstraction of abstraction (Repository) I'm creating a small project, but in the past I've used a Repository pattern for it, and it just seemed too bloated. I ended up having repo classes with huge amounts of queries. I'm trying to move away from that. I invite you to critique/help/guide me on my journey to less abstraction:

Note: I like the syntax style of Simple.Data and "Fluentness" of FluentApi. So my naming/style is inspired by them.

I start off with an IUnitOfWork Interface:

public interface IUnitOfWork : IDisposable
{
    void Save();
    IDbSet&lt;T&gt; Set&lt;T&gt;() where T : class;
}


My DB Context (pretty standard):

public partial class MyDbContext : DbContext, IUnitOfWork
{
    public MyDbContext() : base("DBConnection") { }

    public new IDbSet&lt;T&gt; Set&lt;T&gt;() where T : class
    {
        return base.Set&lt;T&gt;();
    }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new UsersMap());
    }
    public void Save()
    {
        SaveChanges();
    }
}


A Query object/service:

public class UserService : IService
{
    private readonly IUnitOfWork unitOfWork;

    public UserService(IUnitOfWork _u)
    {
        this.unitOfWork = _u;
    }
    public string GetUserName(string Name)
    {
        return unitOfWork.Set&lt;User&gt;().Single(s =&gt; s.Name == Name).UserName;
    }

}


Here's my Database Class (name inspired by Simple.Data):

public sealed partial class Database
{
    private readonly IUnitOfWork context;

    public Database(IUnitOfWork _context = null)
    {
        if (_context == null)
            this.context = new MyDbContext();
        else
            this.context = _context;
    }

    public static Database Open()
    {
        return new Database();
    }

    // I may move these into a separate file:
    public UserService Users { get { return new UserService(context); } }
}


Usage:

var userName = Database.Open().Users.GetUserName("John");
Console.WriteLine(userName);


This is all fine and good for simple tasks. But let's say I want to do multiple things whilst the Database connection is open. I could move Database.Open() to a separate variable then use it like this:

var database = Database.Open();
var userName = database.Users.GetUserName("John");
var userFirstName = database.Users.GetFirstName("john123");


So my question is, am I doing it wrong? Obviously, my main concern is to not open multiple connections to the Database, and use it like a UnitOfWork.

My other question is about how to handle CRUD. I have IService there (currently empty) because I was thinking of putting Insert/Update/Delete in there and adding methods to each Service class - BUT, this turns into a type "Repository" which I was trying to avoid. I don't think it's right for me to expose the DbSet&lt;TEntity&gt;() so I can .Add()/.Attach() - so what should I do here?

I'm still at the planning stage of this, so any changes/recommendations are welcome.
I realize you said


  my naming/style is inspired by them.


But I would still point out some of your naming conventions which don't align with C#s. 


Method/Function level variables should be camelCase instead of PascalCase

public string GetUserName(string Name)
public string GetUserName(string name)

Same as before, and as a note _underscores should only be used for class level variables.

public UserService(IUnitOfWork _u)
public UserService(IUnitOfWork u)

Not required, but a common practice is also that you do indeed use underscores for class level variables

private readonly IUnitOfWork unitOfWork;
private readonly IUnitOfWork _unitOfWork;





Make sure you are disposing(closing) your database object. I presume by the way you have your class setup that when your database object is disposed it will close, in which case I would recommend using the using keyword. Which would make your above code look more like this in practice.

using(var database = Database.Open())
{
    var userName = database.Users.GetUserName("John");
    var userFirstName = database.Users.GetFirstName("john123");
}


This ensures that you are always closing your connection in the end.



Be careful when debugging your code, and remember (depending on your db setup) if you pause the debug in your code while the connection is open, you wont be able to use the database. Also if you have any plans to do mulithreading with this you'll want to use locks.