Generic Repository for SQLite-Net in Xamarin Project

后端 未结 2 884
梦如初夏
梦如初夏 2020-12-07 16:46

I am wondering if there is a way to write a generic repository for my Xamarin project versus writing a different Repository for each entity in my object. The Xamarin Tasky P

2条回答
  •  甜味超标
    2020-12-07 17:35

    This is an old question but here is my implementation.

    I´m using async connections as they provide better performance in mobile projects. The nuggets I installed are Sqlite.Net-PCL/SQLite.Net.Async-PCL on the Core project and the corresponding nuget on the Android project.

    My Repository looks like this:

    using System;
    using System.Collections.Generic;
    using Core.Models;
    using SQLite.Net;
    using System.Linq;
    using SQLite.Net.Async;
    using System.Threading.Tasks;
    using System.Linq.Expressions;
    
    namespace Core.Managers
    {
        public interface IRepository where T : class, new()
        {
            Task> Get();
            Task Get(int id);
            Task> Get(Expression> predicate = null, Expression> orderBy = null);
            Task Get(Expression> predicate);
            AsyncTableQuery AsQueryable();
            Task Insert(T entity);
            Task Update(T entity);
            Task Delete(T entity);
        }
    
        public class Repository : IRepository where T : class, new()
        {
            private SQLiteAsyncConnection db;
    
            public Repository(SQLiteAsyncConnection db)
            {
                this.db = db;
            }
    
            public AsyncTableQuery AsQueryable() => 
                db.Table();
    
            public async Task> Get() => 
                await db.Table().ToListAsync();
    
            public async Task> Get(Expression> predicate = null, Expression> orderBy = null)
            {
                var query = db.Table();
    
                if (predicate != null)
                    query = query.Where(predicate);
    
                if (orderBy != null)
                    query = query.OrderBy(orderBy);
    
                return await query.ToListAsync();
            }
    
            public async Task Get(int id) => 
                 await db.FindAsync(id);
    
            public async Task Get(Expression> predicate) =>
                await db.FindAsync(predicate);
    
            public async Task Insert(T entity) => 
                 await db.InsertAsync(entity);
    
            public async Task Update(T entity) =>
                 await db.UpdateAsync(entity);
    
            public async Task Delete(T entity) =>
                 await db.DeleteAsync(entity);
        }
    }
    

    Some examples on how to use it:

    var connection = new SQLiteAsyncConnection(() => sqlite.GetConnectionWithLock());
    await connection.CreateTablesAsync();
    
    IRepository stockRepo = new Repository(connection);
    IRepository ingredientRepo = new Repository(connection);
    
    var stock1 = new Stock { 
        IngredientId = 1,
        DaysToExpire = 3,
        EntryDate = DateTime.Now,
        Location = StockLocations.Fridge,
        MeasureUnit = MeasureUnits.Liter,
        Price = 5.50m,
        ProductName = "Leche Auchan",
        Quantity = 3,
        Picture = "test.jpg",
        Family = IngredientFamilies.Dairy
    };
    
    var stockId = await stockRepo.Insert(stock1);
    
    var all = await stockRepo.Get();
    var single = await stockRepo.Get(72);
    var search = await stockRepo.Get(x => x.ProductName.StartsWith("something"));
    var orderedSearch = await stockRepo.Get(predicate: x => x.DaysToExpire < 4, orderBy: x => x.EntryDate);
    

    If the Repository does not meet your query needs, you can use AsQueryable():

    public async Task> Search(string searchQuery, StockLocations location, IngredientFamilies family)
    {
        var query = stockRepo.AsQueryable();
    
        if (!string.IsNullOrEmpty(searchQuery))
        {
            query = query.Where(x => x.ProductName.Contains(searchQuery) || x.Barcode.StartsWith(searchQuery));
        }
        if (location != StockLocations.All)
        {
            query = query.Where(x => x.Location == location);
        }
        if (family != IngredientFamilies.All)
        {
            query = query.Where(x => x.Family == family);
        }
    
        return await query.OrderBy(x => x.ExpirationDays).ToListAsync();
    }
    

提交回复
热议问题