0

I'm implementing multi tenants (separate databases for each tenant) in ABP framework with following architect:

  1. Host: Server 1
  2. Tenant 1: Server 1 (the same with host)
  3. Tenant 2: Server 2

In Application layer, I have a method like this:

public async Task<List<ODDetailDto>> GetListAsync(string value)
{
    var formData = new ODDetailFilterDto();
    if (!string.IsNullOrEmpty(value))
        formData = JsonConvert.DeserializeObject<ODDetailFilterDto>(value);
    var queryODDetail = await _odDetailRepository.GetQueryableAsync();
    var queryRemit = await _remittanceTransactionRepository.GetQueryableAsync();
    var queryStatus = await _statusRepository.GetQueryableAsync();
    var query = await AsyncExecuter.ToListAsync(
        from a in queryODDetail
        join b in queryRemit on a.ODRMTTransactionId equals b.Id
        join c in queryStatus on a.VitalStatusId equals c.Id into ac
        from acResult in ac.DefaultIfEmpty()
        where
        (formData.CustomerAbbr != null ? b.CustomerID == formData.CustomerAbbr : true)
            && (!string.IsNullOrEmpty(formData.ODRefNo) ? b.ODRefNo == formData.ODRefNo : true)
            && (formData.ODDate.HasValue ? b.ODDate == formData.ODDate : true)
            && (formData.ODFinalDue.HasValue ? b.ODFinalDueDate == formData.ODFinalDue.Value : true)
            && (formData.ODFinalRate.HasValue ? b.InterestRateFinalRate == formData.ODFinalRate.Value : true)
            && (!string.IsNullOrEmpty(formData.RMTAMTCCY) ? b.RMTCCY == formData.RMTAMTCCY : true)
        //&& (!string.IsNullOrEmpty(formData.LoanPurpose) ? b.purpo == formData.LoanPurpose : true)

        select new ODDetailDto
        {

            Id = a.Id,
            Amount = b.ODAmountAmend.HasValue ? b.ODAmountAmend : b.ODAmount,
            Repayment = a.Event != "OD" ? a.Amount : null,
            Balance = (b.ODAmountAmend.HasValue ? b.ODAmountAmend : b.ODAmount) - (a.Event != "OD" ? (a.Amount.HasValue ? a.Amount.Value : 0) : 0),
            BookingType = a.BookingType,
            SystemRefNo = a.SystemRefNo,
            VitalRefNo = a.VitalRefNo,
            Cost = b.ODTRCost,
            Event = a.Event,
            EventDate = a.EventDate,
            Spread = b.ContractSpread,
            FinalRate = b.InterestRateFinalRate,
            VitalStatusId = a.VitalStatusId,
            VitalStatusName = acResult.StatusName
        }   
    );
    return query;
}

When I run on Tenant 1, it's OK, but not for Tenant 2 with following error:

Cannot use multiple context instances within a single query execution. Ensure the query uses a single context instance.
System.InvalidOperationException: Cannot use multiple context instances within a single query execution. Ensure the query uses a single context instance.

I don't know why because queryODDetail, queryRemit and query are on the same DbContext. Could you please tell me why? Thank you.

Svyatoslav Danyliv
  • 21,911
  • 3
  • 16
  • 32
duyan
  • 63
  • 1
  • 8
  • You cannot create cross context and cross database queries. It is known EF Core limitation. – Svyatoslav Danyliv Nov 15 '22 at 09:42
  • you need to split up your query based on the servers - its possible to check the dbcontext with reflection ( https://stackoverflow.com/questions/53198376/net-ef-core-2-1-get-dbcontext-from-iqueryable-argument ) but you could expose the dbcontext from your repositories by yourself – Puschie Nov 16 '22 at 13:33

0 Answers0