我正在制定一项管理个人财务的计划。我有一个存储所有数据的SQLite数据库,我可以加载/保存帐户,账单,付款等。
我要查看的内容是根据每个PayeeId
的{{1}}加载相关帐户的帐户名称。我知道如何使用SQL实现这一点,但我的数据是使用存储库设置的。例如,我通过调用
Payment
Payments
var payments = await _paymentsRepository.LoadAllAsync();
方法在LoadAllAsync()
类中,看起来像这样:
RepositoryBase
并在public async Task<IEnumerable<TTable>> LoadAllAsync()
{
var query = _sqliteService.Conn.Table<TTable>();
var array = (await query.ToListAsync()).ToArray();
return array;
}
界面中声明如下:
IPaymentsRepository
每个Task<IEnumerable<Payment>> LoadAllAsync();
对象都有Payment
属性,该属性链接到PayeeId
的{{1}}。 Payee
本身并不存储有关Payment
的任何其他信息,但我希望能够加载Payment
属性以显示Payee
信息。有没有一种简单的方法可以做到这一点,或者我是否必须创建一个单独的PayeeName
来存储&#34; hybrid&#34;数据包含Payment
信息以及ViewModel
信息?
修改
我知道我可以使用额外的类来完成此操作,例如Payment
或其他类,并存储Payee
和PaymentInfo
数据,然后像这样访问它:{{1 }或Payment
,但我必须在两个单独的查询中加载它们。虽然这当然是可能的,但我希望能够在一个查询中完成一个解决方案,这就是为什么我要使用Payee
。如果我需要,我将使用LINQ,但我的问题是使用我目前拥有的存储库设置是否可行。
编辑2
这是存储库代码。我试图只包括相关的部分。每个表都有自己的存储库。这是PaymentInfo.Payment.PaymentAmount
:
PaymentInfo.Payee.PayeeName
JOIN
看起来像这样:
PaymentsRepository
public class PaymentsRepository : RepositoryBase<Payment, int>, IPaymentsRepository
{
}
界面:
RepositoryBase<>
public abstract class RepositoryBase<TTable, TKey> : IRepository<TTable, TKey>
where TTable : IKeyedTable<TKey>, new()
{
protected readonly ISqliteService SqliteService;
protected RepositoryBase(ISqliteService sqlLiteService)
{
SqliteService = sqlLiteService;
}
public async Task<IEnumerable<TTable>> LoadAllAsync()
{
var query = SqliteService.Conn.Table<TTable>();
var array = (await query.ToListAsync()).ToArray();
return array;
}
......
}
:
IRepository
使用内置的SQLite方法最终会针对interface IRepository<TTable, in TKey>
where TTable : IKeyedTable<TKey>, new()
{
Task<TTable> LoadByIdAsync(TKey id);
Task<IEnumerable<TTable>> LoadAllAsync();
Task InsertAsync(TTable item);
Task UpdateAsync(TTable item);
Task DeleteAsync(TTable item);
AsyncTableQuery<TTable> Query();
}
属性查询所有内容。例如,在ISqliteService
函数中,public interface ISqliteService
{
SQLiteAsyncConnection Conn { get; }
Task<object> ClearLocalDb();
void Reconnect();
}
使用此:
SQLiteAsyncConnection
位于LoadAllAsync()
答案 0 :(得分:1)
我无法找到使用LINQ直接查询两个不同表的方法,但我使用了“混合”类。我刚刚创建了一个PaymentInfo
类,它具有Payment
属性和Payee
属性,指向相关数据。我在PaymentsRepository
添加了一个方法,如下所示:
public async Task<IEnumerable<PaymentInfo>> LoadAllPaymentInfoAsync()
{
var payments = await SqliteService.Conn.Table<Payment>().ToListAsync();
var payees = await SqliteService.Conn.Table<Payee>().ToListAsync();
var query = from p1 in payments
join p2 in payees on p1.PayeeId equals p2.Id
select new PaymentInfo() {Payment = p1, Payee = p2};
return query;
}
我确信这不一定是实现这一目标的最佳方法,但我想我会在这里分享,以防有人遇到这个页面,想要做我做的事情。
答案 1 :(得分:0)
我认为你可以获得IQueryable<Payment>
和IQueryable<Payee>
,在LINQ中加入它们,然后在结果上调用.ToArray()。
它将构建查询并仅在您实际访问数据时执行它(在本例中,在ToArray()调用上)。 我相信这会生成一个查询。