C# 如何避免嵌套使用?
我编写了一个代码,从两个不同的数据库返回一个列表。这两个dbcontext之间的联合字段是C# 如何避免嵌套使用?,c#,sql,asp.net-mvc,entity-framework,using,C#,Sql,Asp.net Mvc,Entity Framework,Using,我编写了一个代码,从两个不同的数据库返回一个列表。这两个dbcontext之间的联合字段是accountid和email(两者的值相同)。因为有两个不同的数据库,所以我不能在实体框架中使用连接。所以我对每个块使用了嵌套的和。这是我的密码: namespace AdminMvc.Components.BankDepositHistory { public class BankDepositHistoryHelper { public static List<B
accountid
和email
(两者的值相同)。因为有两个不同的数据库,所以我不能在实体框架中使用连接。所以我对每个块使用了嵌套的和。这是我的密码:
namespace AdminMvc.Components.BankDepositHistory
{
public class BankDepositHistoryHelper
{
public static List<BankDepositHistoryItemDto> GetChangeRequestsList(int skip, int take, out int total, string name, string email, AvailableBankDepositStates state)
{
using (var myketAdsDB = new MyketAdsEntities())
{
using (var myketDB = new MyketReadOnlyDb())
{
#region DefaultQuery
var bankDepositHistories = myketAdsDB.BankDepositHistories.AsQueryable();
#endregion
#region Filtering
if (!string.IsNullOrWhiteSpace(name))
{
var emails = myketDB.AppDevelopers
.Where(n => n.RealName.Contains(name))
.Select(e => e.Email).ToList();
// emails.Add(email);
if (emails.Count > 0)
{
bankDepositHistories = bankDepositHistories.Where(e => emails.Contains(e.AccountId));
}
}
if (!string.IsNullOrWhiteSpace(email))
{
bankDepositHistories = bankDepositHistories.Where(a => a.AccountId.Contains(email));
}
if (state != AvailableBankDepositStates.All)
{
bankDepositHistories = state == AvailableBankDepositStates.Success ?
bankDepositHistories.Where(x => x.State == AvailableBankDepositStates.Success.ToString()) :
bankDepositHistories.Where(x => x.State == AvailableBankDepositStates.Fail.ToString());
}
else
{
bankDepositHistories = bankDepositHistories.
Where(x => x.State != BankDepositState.Start.ToString());
}
#endregion
#region GetingTotalpages
total = bankDepositHistories.Count();
#endregion
#region Pagination
var pageResult = bankDepositHistories.OrderByDescending(ba => ba.CreationDate).Skip(skip).Take(take).ToList();
#endregion
#region FillingDomainObjects
var emailFilter = pageResult.Select(r => r.AccountId).ToList();
var developers = myketDB.AppDevelopers.Where(a => emailFilter.Contains(a.Email)).
Select(r => new { r.RealName, r.Email }).ToList();
var result = pageResult
.Select(b => new BankDepositHistoryItemDto()
{
Id = b.Id,
AccountId = b.AccountId,
Amount = b.Amount,
ClientIp = b.ClientIp,
State = (BankDepositState)Enum.Parse(typeof(BankDepositState), b.State, true),
ReturnUrl = b.ReturnUrl,
AdditionalData = b.AdditionalData,
Gateway = b.Gateway,
CreationDate = b.CreationDate,
PaymentRefNumber = b.PaymentRefNumber,
Uuid = b.Uuid,
}).ToList();
foreach (var bankDepositHistory in result)
{
foreach (var developer in developers)
{
if (bankDepositHistory.AccountId == developer.Email)
{
bankDepositHistory.RealName = developer.RealName;
}
}
}
return result;
#endregion
}
}
}
名称空间AdminMvc.Components.bankDepositorHistory
{
公共类BankDepositoryHistoryHelper
{
公共静态列表GetChangeRequestsList(int skip、int take、out int total、字符串名称、字符串电子邮件、AvailableBankDepositStates状态)
{
使用(var myketAdsDB=new MyketAdsEntities())
{
使用(var myketDB=new MyketReadOnlyDb())
{
#区域默认查询
var bankDepositHistories=myketAdsDB.bankDepositHistories.AsQueryable();
#端区
#区域滤波
如果(!string.IsNullOrWhiteSpace(名称))
{
var emails=myketDB.AppDevelopers
.Where(n=>n.RealName.Contains(name))
.Select(e=>e.Email).ToList();
//电子邮件。添加(电子邮件);
如果(emails.Count>0)
{
bankDepositHistories=bankDepositHistories.Where(e=>emails.Contains(e.AccountId));
}
}
如果(!string.IsNullOrWhiteSpace(电子邮件))
{
bankDepositHistories=bankDepositHistories.Where(a=>a.AccountId.Contains(email));
}
if(state!=AvailableBankDepositStates.All)
{
bankDepositHistories=状态==可用的银行存款状态。是否成功?
bankDepositHistories.Where(x=>x.State==AvailableBankDepositStates.Success.ToString()):
bankDepositHistories.Where(x=>x.State==AvailableBankDepositStates.Fail.ToString());
}
其他的
{
银行存款历史记录=银行存款历史记录。
其中(x=>x.State!=BankDepositState.Start.ToString());
}
#端区
#区域获取总页面数
总计=银行存款历史记录。计数();
#端区
#区域分页
var pageResult=bankDepositorHistories.OrderByDescending(ba=>ba.CreationDate).Skip(Skip.Take(Take.ToList();
#端区
#区域填充域对象
var emailFilter=pageResult.Select(r=>r.AccountId.ToList();
var developers=myketDB.AppDevelopers.Where(a=>emailFilter.Contains(a.Email))。
选择(r=>new{r.RealName,r.Email}).ToList();
var result=pageResult
.Select(b=>newbankDepositoryItemTo()
{
Id=b.Id,
AccountId=b.AccountId,
金额=b.金额,
ClientIp=b.ClientIp,
State=(BankDepositState)Enum.Parse(typeof(BankDepositState),b.State,true),
ReturnUrl=b.ReturnUrl,
附加数据=b.附加数据,
网关=b.网关,
肌酸盐=肌酸盐,
PaymentRefNumber=b.PaymentRefNumber,
Uuid=b.Uuid,
}).ToList();
foreach(结果中的var bankDepositHistory)
{
foreach(开发者中的var开发者)
{
if(bankDepositHistory.AccountId==developer.Email)
{
bankDepositHistory.RealName=developer.RealName;
}
}
}
返回结果;
#端区
}
}
}
我想知道是否有可能避免使用嵌套的using,并为每个数据库编写一个单独的using。您可以按自己的要求执行。来自内部using的电子邮件列表会影响来自外部using的bankDepositHistories
,但外部查询直到稍后才会执行。(另外,最初的内部使用不依赖于外部的任何东西,因此可以移动到外部)
因此,首先使用myketDB
获取电子邮件列表:
List<Email> emails = new List<Email>();
using (var myketDB = new MyketReadOnlyDb())
{
if (!string.IsNullOrWhiteSpace(name))
{
emails = myketDB.AppDevelopers
.Where(n => n.RealName.Contains(name))
.Select(e => e.Email).ToList();
}
}
// original outer using is now after the above
列出电子邮件=新建列表();
使用(var myketDB=new MyketReadOnlyDb())
{
如果(!string.IsNullOrWhiteSpace(名称))
{
电子邮件=myketDB.AppDevelopers
.Where(n=>n.RealName.Contains(name))
.Select(e=>e.Email).ToList();
}
}
//最初的外部使用现在是在上述之后
然后通过将原始代码中的外部using ofmyketAdsDB
移动到上面using的下方来执行所有其他逻辑。这是一个接一个的,而不是嵌套的
如果您所做的不一定是事务性的,则最好按顺序访问上下文,因为您不必无缘无故地延长外部上下文的生存期。在外部上下文的内部运行可延长外部上下文的生存期。您可以按要求执行操作。内部使用的电子邮件列表会影响ode>bankDepositHistories,它们来自外部使用,但外部查询直到稍后才会执行。(此外,原始内部使用不依赖于外部中的任何内容,因此可以移动到外部)
所以,去
public static List<BankDepositHistoryItemDto> GetChangeRequestsList(int skip, int take, out int total, string name, string email, AvailableBankDepositStates state)
{
var statesFilter = new Dictionary<AvailableBankDepositStates, Func<IQueryable<BankDepositHistory>, IQueryable<BankDepositHistory>>>()
{
{ AvailableBankDepositStates.All, bdh => bdh.Where(x => x.State != BankDepositState.Start.ToString()) },
{ AvailableBankDepositStates.Success, bdh => bdh.Where(x => x.State == AvailableBankDepositStates.Success.ToString()) },
{ AvailableBankDepositStates.Fail, bdh => bdh.Where(x => x.State == AvailableBankDepositStates.Fail.ToString()) },
};
List<string> emails = new List<string>();
ILookup<string, string> developers = null;
using (var myketDB = new MyketReadOnlyDb())
{
if (!string.IsNullOrWhiteSpace(name))
{
emails = myketDB.AppDevelopers.Where(n => n.RealName.Contains(name)).Select(e => e.Email).ToList();
}
developers = myketDB.AppDevelopers.ToLookup(x => x.Email, x => x.RealName);
}
using (var myketAdsDB = new MyketAdsEntities())
{
var bankDepositHistories = myketAdsDB.BankDepositHistories.AsQueryable();
if (emails.Count() > 0)
{
bankDepositHistories = bankDepositHistories.Where(e => emails.Contains(e.AccountId));
}
if (!string.IsNullOrWhiteSpace(email))
{
bankDepositHistories = bankDepositHistories.Where(a => a.AccountId.Contains(email));
}
bankDepositHistories = statesFilter[state](bankDepositHistories);
total = bankDepositHistories.Count();
var result =
bankDepositHistories
.OrderByDescending(ba => ba.CreationDate)
.Skip(skip)
.Take(take)
.ToList()
.Select(b => new BankDepositHistoryItemDto()
{
Id = b.Id,
AccountId = b.AccountId,
Amount = b.Amount,
ClientIp = b.ClientIp,
State = (BankDepositState)Enum.Parse(typeof(BankDepositState), b.State, true),
ReturnUrl = b.ReturnUrl,
AdditionalData = b.AdditionalData,
Gateway = b.Gateway,
CreationDate = b.CreationDate,
PaymentRefNumber = b.PaymentRefNumber,
Uuid = b.Uuid,
RealName = developers[b.AccountId].LastOrDefault(),
}).ToList();
return result;
}
}
public enum AvailableBankDepositStates
{
All, Success, Fail
}
public enum BankDepositState
{
Start
}
public class BankDepositHistoryItemDto
{
public string AccountId;
public BankDepositState State;
public DateTime CreationDate;
public string RealName;
}
public class MyketAdsEntities : IDisposable
{
public IEnumerable<BankDepositHistory> BankDepositHistories;
public void Dispose()
{
throw new NotImplementedException();
}
}
public class MyketReadOnlyDb : IDisposable
{
public IEnumerable<AppDeveloper> AppDevelopers;
public void Dispose()
{
throw new NotImplementedException();
}
}
public class BankDepositHistory
{
public string AccountId;
public string State;
public DateTime CreationDate;
}
public class AppDeveloper
{
public string RealName;
public string Email;
}