Use OUTER APPLY for SqlQuery<T> where T has IEnumerable properties - entity-framework-6

I am using a string sql query because of performance issues with using Linq. Due to a lot of outer applies, and a lot of where clauses using IN. The code in this sample is reduced for clarity here. I left off the IF-ELSE statements that added (or not) a lot of code to the where clause.
Here is my business object, it has an IEnumerable as a property.
public class AssetBO
{
public Guid AssetId { get; set; }
public Guid SiteId { get; set; }
public string Name { get; set; }
public IEnumerable<AssetDivisionBO> AssetDivisionInfo { get; set; }
}
And here is my string sql:
string SQL_Data = #"SELECT DISTINCT e.AssetId, e.SiteId, e.Name
FROM
Asset.vAssetLinkBox e
OUTER APPLY (
SELECT
ld.AssetDivisionId,
ld.SiteId,
ld.AssetId,
ld.DivisionId,
ld.IsDeleted,
ld.Created,
ld.LastModified,
ld.ModifiedByEmployeeId,
ld.CreatedByEmployeeId,
FROM Asset.AssetDivision ld
WHERE
ld.IsDeleted = 0
AND ld.AssetId = e.AssetId
) AS AssetDivisionInfo
WHERE
e.IsDeleted = 0";
I then run this:
var query = context.Database.SqlQuery<AssetBO>(SQL_Data);
List<AssetBO> assets = query.ToList<AssetBO>();
I would like to populate the IEnumerable AssetDivisionInfo, from the OUTER APPLY in the string SQL. Is this possible?
I get my AssetBO object, and the AssetDivisionInfo is null. Is there a way to map it?
EDIT: I was asked to supply the original Linq, so posting it here now. I need all of those OUTER APPLIES returned with the data.
public static List<ModuleView.AssetBO> Asset_GetList_ByRadFilter(COG_ContextDB context, RadFilter filter, string where_clause,
Guid Base_ContextSiteId, Guid Base_ContextEmployeeId, HashSet<Guid> PassedAssetIdList,
bool Base_ContextEmployee_IsForAllDivisions,
int PageNumber, int PageSize, string OrderByField, bool IsDescending,
bool IsRestrictedByDivision, HashSet<Guid?> Employee_DivisionIdList, out int RecordCount)
{
var interceptor = new Common.BLL.CommandInterceptorHelper();
System.Data.Entity.Infrastructure.Interception.DbInterception.Add(interceptor);
HashSet<Guid> IsForAll_AssetIdList = new HashSet<Guid>();
if (IsRestrictedByDivision == true)
{
//db hit, so calling only if IsRestrictedByDivision == true
IsForAll_AssetIdList = GetIsForAllDivisions_Assets(context, Base_ContextSiteId);
}
else
{
Base_ContextEmployee_IsForAllDivisions = false;
}
var query = from e in context.vAssetLinkBoxes
from cbu in context.Employees.Where(emp => emp.EmployeeId == e.CreatedByEmployeeId && emp.IsDeleted == false).DefaultIfEmpty()
//OUTER APPLY to get a list of AssetIds from AssetDivision table, that are in the employees DivisionIdList (divisions he has access to.) DEV-3504
let AssetIdList = (from dv in context.AssetDivisions.Where(div => div.AssetId == e.AssetId && div.IsDeleted == false && Employee_DivisionIdList.Contains(div.DivisionId)) select dv.AssetId).ToList<Guid>()
join assetUsageInfo in
(
from e in context.AssetUsages
from cbu in context.Employees.Where(emp => emp.EmployeeId == e.CreatedByEmployeeId && emp.IsDeleted == false).DefaultIfEmpty()
where e.IsDeleted == false
select new ModuleView.AssetUsageBO
{
AssetUsageId = e.AssetUsageId,
SiteId = e.SiteId,
AssetId = e.AssetId,
AssetUsageTypeId = e.AssetUsageTypeId,
ImportId = e.ImportId,
IsDeleted = e.IsDeleted,
Created = e.Created,
LastModified = e.LastModified,
ModifiedByEmployeeId = e.ModifiedByEmployeeId,
CreatedByEmployeeId = e.CreatedByEmployeeId,
CreatedByEmployeeName = (!string.IsNullOrEmpty(cbu.FirstName)) ? cbu.LastName + ", " + cbu.FirstName : cbu.LastName,
IsDirty = false,
IsNew = false,
}
) on e.AssetId equals assetUsageInfo.AssetId into assetUsageInfos
join assetExtendedFieldInfo in
(
from e in context.AssetExtendedFields
from cbu in context.Employees.Where(emp => emp.EmployeeId == e.CreatedByEmployeeId && emp.IsDeleted == false).DefaultIfEmpty()
where e.IsDeleted == false
orderby e.FieldName
select new ModuleView.AssetExtendedFieldBO
{
AssetExtendedFieldId = e.AssetExtendedFieldId,
SiteId = e.SiteId,
AssetId = e.AssetId,
FieldName = e.FieldName,
FieldLabel = e.FieldLabel,
FieldValue = e.FieldValue,
FieldDataType = e.FieldDataType,
IsDeleted = e.IsDeleted,
Created = e.Created,
LastModified = e.LastModified,
ModifiedByEmployeeId = e.ModifiedByEmployeeId,
CreatedByEmployeeId = e.CreatedByEmployeeId,
CreatedByEmployeeName = (!string.IsNullOrEmpty(cbu.FirstName)) ? cbu.LastName + ", " + cbu.FirstName : cbu.LastName,
IsDirty = false,
IsNew = false,
}
) on e.AssetId equals assetExtendedFieldInfo.AssetId into assetExtendedFieldInfos
join assetDivisionInfo in
(
from e in context.AssetDivisions
from d in context.Divisions.Where(emp => emp.DivisionId == e.DivisionId && emp.IsDeleted == false)
from a in context.Assets.Where(emp => emp.AssetId == e.AssetId && emp.IsDeleted == false)
from cbu in context.Employees.Where(emp => emp.EmployeeId == e.CreatedByEmployeeId && emp.IsDeleted == false).DefaultIfEmpty()
where e.IsDeleted == false
select new ModuleView.AssetDivisionBO
{
AssetDivisionId = e.AssetDivisionId,
SiteId = e.SiteId,
AssetId = e.AssetId,
DivisionId = e.DivisionId,
IsDeleted = e.IsDeleted,
Created = e.Created,
LastModified = e.LastModified,
ModifiedByEmployeeId = e.ModifiedByEmployeeId,
CreatedByEmployeeId = e.CreatedByEmployeeId,
CreatedByEmployeeName = (!string.IsNullOrEmpty(cbu.FirstName)) ? cbu.LastName + ", " + cbu.FirstName : cbu.LastName,
DivisionName = d.DivisionName,
AssetName = a.Name,
IsDirty = false,
IsNew = false,
}
) on e.AssetId equals assetDivisionInfo.AssetId into assetDivisionInfos
where e.SiteId == Base_ContextSiteId
&& (IsRestrictedByDivision == false || (IsRestrictedByDivision == true && (Base_ContextEmployee_IsForAllDivisions == true || AssetIdList.Contains(e.AssetId) || IsForAll_AssetIdList.Contains(e.AssetId)))) //from outer apply
select new ModuleView.AssetBO
{
AssetId = e.AssetId,
SiteId = e.SiteId,
AssetTypeId = e.AssetTypeId,
Name = e.Name,
Description = e.Description,
UniqueIdentity = e.UniqueIdentity,
StatusId = e.StatusId,
CompanyId = e.CompanyId,
Make = e.Make,
Model = e.Model,
Year = e.Year,
SerialNumber = e.SerialNumber,
PhoneNumber = e.PhoneNumber,
Email = e.Email,
IsActive = e.IsActive,
BlockedTimeIsEnabled = e.BlockedTimeIsEnabled,
ImportId = e.ImportId,
IsForAllDivisions = e.IsForAllDivisions,
IsDeleted = e.IsDeleted,
Created = e.Created,
LastModified = e.LastModified,
ModifiedByEmployeeId = e.ModifiedByEmployeeId,
AssetTypeName = e.AssetTypeName,
StatusName = e.StatusName,
CompanyName = e.CompanyName,
ModifiedByEmployeeName = e.ModifiedByEmployeeName,
AssetUsageTypeId = e.AssetUsageTypeId,
NumCaptainsOnBoard = (e.CaptainNum == null) ? 0 : (int)e.CaptainNum,
ActivityTimeInMin = e.TotalDurationInMin,
AssetUsageInfo = assetUsageInfos,
CreatedByEmployeeId = e.CreatedByEmployeeId,
CreatedByEmployeeName = (!string.IsNullOrEmpty(cbu.FirstName)) ? cbu.LastName + ", " + cbu.FirstName : cbu.LastName,
AssetExtendedFieldInfo = assetExtendedFieldInfos,
AssetDivisionInfo = assetDivisionInfos,
DivisionDelimitedString = "", //must be here to avoid error when sorting. Sort is done in BA code.
};
if (string.IsNullOrEmpty(where_clause))
{
where_clause = DataFilterBA.GetFilterWhereClause(context, filter, "ASSET", Base_ContextEmployeeId, Base_ContextSiteId, "LINQ");
}
int SkipRows = (PageNumber - 1) * PageSize;
if (PassedAssetIdList.Count == 0)
{
RecordCount = query.Where(where_clause).Select(d => d.AssetId).Distinct().Count();
//RecordCount = query.Where(where_clause).GroupBy(test => test.AssetId)
// .Select(grp => grp.FirstOrDefault()).Count();
query = query.Where(where_clause).OrderBy(OrderByField + (IsDescending ? " descending" : ""));
}
else
{
RecordCount = query.Where(x => PassedAssetIdList.Contains(x.AssetId)).Where(where_clause).Select(d => d.AssetId).Distinct().Count();
query = query.Where(x => PassedAssetIdList.Contains(x.AssetId)).Where(where_clause).OrderBy(OrderByField + (IsDescending ? " descending" : ""));
}
List<ModuleView.AssetBO> items = new List<ModuleView.AssetBO>();
if (PageSize == -1)
{
items = query.ToList<ModuleView.AssetBO>();
}
else
{
items = query.Skip(SkipRows).Take(PageSize).ToList<ModuleView.AssetBO>();
}
System.Data.Entity.Infrastructure.Interception.DbInterception.Remove(interceptor);
if (items != null && items.Count > 0)
{
items = items.GroupBy(test => test.AssetId)
.Select(grp => grp.FirstOrDefault())
.ToList();
return items;
}
return new List<ModuleView.AssetBO>();
}

Related

How to instantly access the saved row

I was wrote some code in Asp MVC with EF technology, I have condition line to find row with today date if i was not found i add it to database and then use the saved row for another process, but i get error when i refresh error page it work fine ! i think my code can not work async!
any body can help me to found my wrong ?
public ActionResult LineRegimeSave(string breakFast, string snake1, string lunch, string snake2, string snake3,string dinner, string snake4,string adviseText, string docFooterId)
{
ApplicationDbContext myContext = new ApplicationDbContext();
var docFooter = docFooterId != "null" ? myContext.DocFooters.Single(d => d.Id.ToString() == docFooterId) : null;
var strLine="BreakFast,"+ breakFast + "/Snake1,"+ snake1 + "/Lunch,"+ lunch + "/Snake2,"+ snake2 + "/Snake3,"+ snake3 + "/Dinner,"+ dinner + "/Snake4,"+snake4;
TriageRecord getMedicalRecId;
var userId = Session["NID"];
var userProfile = myContext.UserProfiles.Single(b => b.NationalId.ToString() == userId.ToString());
getMedicalRecId = myContext.TriageRecords.Where(u => u.UserProfile.Id == userProfile.Id)
.OrderByDescending(d => d.DateTime).First();
if (getMedicalRecId.DateTime.Date != DateTime.Today)
{
TriageRecord insert = new TriageRecord
{
Bust = getMedicalRecId.Bust,
Diastolic = getMedicalRecId.Diastolic,
HeartRate = getMedicalRecId.HeartRate,
Systolic = getMedicalRecId.Systolic,
Height = getMedicalRecId.Height,
Weight = getMedicalRecId.Weight,
Wrist = getMedicalRecId.Wrist,
Waist = getMedicalRecId.Waist,
Hips = getMedicalRecId.Hips,
UserProfile = getMedicalRecId.UserProfile,
DateTime = DateTime.Now
};
insert.MedicalRecord = new MedicalRecord
{
TriageRecord = insert,
VisitDate = DateTime.Now,
};
myContext.TriageRecords.Add(insert);
myContext.SaveChanges();
getMedicalRecId = myContext.TriageRecords.Where(u => u.UserProfile.Id == userProfile.Id)
.OrderByDescending(d => d.DateTime).First();
getMedicalRecId.MedicalRecord.MedicalRecordDetails.Add
(
new MedicalRecordDetail
{
DateTime = DateTime.Now,
VisitMode = "LineDiet",
VisitSummary = strLine,
DocFooter = docFooter,
AdviseText = adviseText
}
);
myContext.SaveChanges();
}
else
{
getMedicalRecId.MedicalRecord.MedicalRecordDetails.Add
(
new MedicalRecordDetail
{
DateTime = DateTime.Now,
VisitMode = "LineDiet",
VisitSummary = strLine,
DocFooter = docFooter,
AdviseText = adviseText
}
);
myContext.SaveChanges();
}
return RedirectToAction("LineRegimePrint",new { id = getMedicalRecId.Id});
}
Error occur on this line :
getMedicalRecId.MedicalRecord.MedicalRecordDetails.Add
(
new MedicalRecordDetail
{
DateTime = DateTime.Now,
VisitMode = "LineDiet",
VisitSummary = strLine,
DocFooter = docFooter,
AdviseText = adviseText
}
);
Error text is : Null reference...
Thank you.
update :
insert.MedicalRecord = new MedicalRecord
{
TriageRecord = insert,
VisitDate = DateTime.Now,
};
myContext.TriageRecords.Add(insert);
myContext.SaveChanges();
Do i need to change this code ?
var a = insert.MedicalRecord = new MedicalRecord
{
TriageRecord = insert,
VisitDate = DateTime.Now,
};
myContext.TriageRecords.Add(insert);
myContext.MedicalRecords.Add(a);
So according to you the problem occurs whenever you try to add an item to the list, but it says the object is null, so you need to check for that.
public ActionResult LineRegimeSave(string breakFast, string snake1, string lunch, string snake2, string snake3,string dinner, string snake4,string adviseText, string docFooterId)
{
...
getMedicalRecId = myContext.TriageRecords.Where(u => u.UserProfile.Id == userProfile.Id).OrderByDescending(d => d.DateTime).First();
if(getMedicalRecId != null) {
if (getMedicalRecId.DateTime.Date != DateTime.Today)
{
...
insert.MedicalRecord = new MedicalRecord
{
TriageRecord = insert,
VisitDate = DateTime.Now,
MedicalRecordDetails = new List<MedicalRecordDetail>(){ new MedicalRecordDetail
{
DateTime = DateTime.Now,
VisitMode = "LineDiet",
VisitSummary = strLine,
DocFooter = docFooter,
AdviseText = adviseText
}
};
myContext.SaveChanges();
}
}
else
{
....
}
else
{
throw new Exception("The current user profile has no triage records!");
}
return RedirectToAction("LineRegimePrint",new { id = getMedicalRecId.Id});
}

asp.net mvc core A second operation was started on the context before the first operation is completed

I am using this code for authorization on controllers.
with [Authorize(Policy = "CustomRole")]
The thing happened that after 3 or 4 request it fails with
A second operation started on this context before a previous operation completed
public class CustomRoleRequirement : AuthorizationHandler<CustomRoleRequirement>, IAuthorizationRequirement
{
public CMSContext _context = new CMSContext();
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomRoleRequirement requirement)
{
var routeobj = context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext;
var c = routeobj.RouteData.Values.Values.ToList();
var keys = routeobj.RouteData.Values.Keys.ToList();
string area = "";
string id = "";
string controller = "";
string action = "";
string module = "";
foreach (var item in keys)
{
if (item=="area")
{
int indexs = keys.FindIndex(cc => cc == "area");
area = c[indexs].ToString();
}
else if (item == "id")
{
int indexs = keys.FindIndex(cc => cc == "id");
id = c[indexs].ToString();
}
else if (item == "controller")
{
int indexs = keys.FindIndex(cc => cc == "controller");
controller = c[indexs].ToString();
}
else if (item == "module")
{
int indexs = keys.FindIndex(cc => cc == "module");
module = c[indexs].ToString();
}
else if (item == "action")
{
int indexs = keys.FindIndex(cc => cc == "action");
action = c[indexs].ToString();
}
}
string modulelink = controller;
if (!string.IsNullOrEmpty(module))
{
modulelink = modulelink + "/" + module;
}
List<string> Roles = new List<string>();
int UserId = Auth.UserID;
string UserName = Auth.UserName;
if (UserName == "superadmin")
{
context.Succeed(requirement);
return Task.CompletedTask;
}
else
{
// apparently the error occurred here
var moduleobj = _context.AppModules.FirstOrDefault(q => q.Link == modulelink);
if (moduleobj != null)
{ // 69 role is assessing news module
//60 role is accessing page module
var RolesModulesobj = _context.AppRolesModules.FirstOrDefault(q => q.ModuleId == moduleobj.ModuleId && q.RolesId == Auth.RoleId);
if (RolesModulesobj != null)
{
string permissionsobj = RolesModulesobj.Permissions;
List<string> PermissionsListobj = permissionsobj.Split(',').Select(x => x.Trim()).ToList();
var FindFullAccess = PermissionsListobj.FirstOrDefault(q => q.Contains("FullAccess:true"));
if (FindFullAccess != null)
{
context.Succeed(requirement);
return Task.CompletedTask;
}
else
{
var abc = PermissionsListobj.FirstOrDefault(q => q.Contains(action + ":true"));
if (abc != null)
{
context.Succeed(requirement);
return Task.CompletedTask;
}
else
{
context.Fail();
return Task.CompletedTask;
}
}
}
}
}
The error occurred at this line above
var moduleobj = _context.AppModules.FirstOrDefault(q => q.Link == modulelink);
How can I make task wait before the second operation started in the method above?
You can't use a singleton DB context. You either create one each time you need one or you pool them.

Sorting Details Page MVC

I cant figured out how perform sort in a details page. I have a classic page with list of order and for each row i have a actionlink to return details view of that order.
i try this
public ActionResult Details(int? anno,int? nr, string centro, string sortOrder)
{
ViewBag.Codice = String.IsNullOrEmpty(sortOrder) ? "Articolo_desc" : "";
if (anno == null && nr == null && string.IsNullOrEmpty(centro))
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
else
{
string s = "anno=" + Request.QueryString["anno"] + "&nr=" + Request.QueryString["nr"] + "&centro=" + Request.QueryString["centro"];
ViewBag.search = s.Replace("search=", "").Replace("%3D", "=");
}
var righe = from d in db.DETAILS
where d.Anno == anno && d.Num == nr && d.Centro == centro
select new DetailsOrdersView
{
Articolo = r.Codice,
...
};
if (righe == null)
return HttpNotFound();
switch(sortOrder)
{
case "Articolo_desc":
righe = righe.OrderByDescending(i => i.Articolo);
break;
default:
righe = righe.OrderBy(i => i.Articolo);
break;
}
return View(righe);
}
}
and in details view
#Html.ActionLink("codice","Details", new { sortOrder = ViewBag.Codice, ViewBag.search })
but i on sorting I get bad request and this is the route
Orders/Details?sortOrder=Articolo_desc&search=anno%3D2017%26nr%3D6%26centro%3D1
#Html.ActionLink("codice", "Details", new { sortOrder = ViewBag.Codice, anno = ViewBag.Anno, centro = ViewBag.Centro , nr= ViewBag.Numero })
i solved as above

Convert SQL command to MVC or lambda code

I want this query in lambda expression:
Insert into Tbl_Bill (EmpID, TotalBill, BillByEmployee, BillBySBI, CreatedDate, UpdatedDate, OrderIDs)
select
EmpID, Sum(TotalBill), Sum(TotalBill), Sum(TotalBill),
MIN(CreatedDate), MIN(CreatedDate), COUNT(OrderID)
from
Tbl_Order
group by
EmpID;
Use LinqPad, its a superb tool to queries to linq queries
var queryTbl_Bill =
from Tbl_Order in db.Tbl_Order
group Tbl_Order by new
{
Tbl_Order.EmpID
} into g
select new
{
g.Key.EmpID,
Column1 = g.Sum(p => p.TotalBill),
Column2 = g.Sum(p => p.TotalBill),
Column3 = g.Sum(p => p.TotalBill),
Column4 = g.Min(p => p.CreatedDate),
Column5 = g.Min(p => p.CreatedDate),
Column6 = g.Count(p => p.OrderID != null)
};
foreach (var q in queryTbl_Bill)
{
decimal sbi = 0, emp = 0;
if (q.Column1 < 100.0M)
{
sbi = q.Column1 * 0.75M;
emp = q.Column1 * 0.25M;
}
else if (q.Column1 > 100.0M)
{
sbi = 75.0M;
decimal temp = q.Column1 - 100.0M;
emp = temp + 25.0M;
}
Tbl_Bill iTbl_Bill = new Tbl_Bill
{
EmpID = q.EmpID,
TotalBill = q.Column1,
BillByEmployee = emp,
BillBySBI = sbi,
CreatedDate = DateTime.Now,
UpdatedDate = DateTime.Now,
OrderIDs = q.Column6.ToString(),
Status=true
};
db.Tbl_Bill.Add(iTbl_Bill);
}
db.SaveChanges();
i got answer using linqer

Convert query ToListAsync in separate method, not ActionResult

I am trying to 'convert' a query to List while using async to retrieve the values to a list and return the NewsListViewModel to my controller as a success or failure like so:
var model = await db.News.Where(n => n.newsPublished == false
&& n.newsTitle.Contains(query)
|| n.newsDescription.Contains(query)).
OrderBy(n => n.newsCreatedDate).Select(n => new List<NewsListViewModel>
{
NewsCreatorFName = n.Profile.profileFirstName,
NewsCreatorLName = n.Profile.profileLastName,
NewsID = n.newsID,
NewsCreatorID = n.userID,
NewsTitle = n.newsTitle,
CreatedDate = n.newsCreatedDate
})
.ToListAsync();
or like this:
public static async Task<List<NewsListViewModel>> GetAllNotPublished(string query)
{
if (query != "" && query != null)
{
var model = (from n in db.News
where n.newsPublished == false && n.newsTitle.Contains(query)
|| n.newsDescription.Contains(query)
orderby n.newsCreatedDate
select new NewsListViewModel
{
NewsCreatorFName = n.Profile.profileFirstName,
NewsCreatorLName = n.Profile.profileLastName,
NewsID = n.newsID,
NewsCreatorID = n.userID,
NewsTitle = n.newsTitle,
CreatedDate = n.newsCreatedDate
});
return await model.ToListAsync();
}
else
{
var model = (from n in db.News
where n.newsPublished == false
orderby n.newsCreatedDate
select new NewsListViewModel
{
NewsCreatorFName = n.Profile.profileFirstName,
NewsCreatorLName = n.Profile.profileLastName,
NewsID = n.newsID,
NewsCreatorID = n.userID,
NewsTitle = n.newsTitle,
CreatedDate = n.newsCreatedDate
});
return await model.ToListAsync();
}
}
I am probably going about this bass akwards and WAAAAY wrong but I have been battling with this for hours now trying to figure it out and can't find any examples that look similar.
One thing is that I can return either one just fine if it is in the ActionResult which is strange to me. This below works just fine, but I don't want it in the ActionResult. I would like to have the list retrieval portion in a separate method.
Thanks in advance for any help.
public async Task<ActionResult> PublishList(string query)
{
if (query != "" && query != null)
{
var model = (from n in db.News
where n.newsPublished == false && n.newsTitle.Contains(query)
|| n.newsDescription.Contains(query)
orderby n.newsCreatedDate
select new NewsListViewModel
{
NewsCreatorFName = n.Profile.profileFirstName,
NewsCreatorLName = n.Profile.profileLastName,
NewsID = n.newsID,
NewsCreatorID = n.userID,
NewsTitle = n.newsTitle,
CreatedDate = n.newsCreatedDate
});
return View(await model.ToListAsync());
}
else
{
var model = (from n in db.News
where n.newsPublished == false
orderby n.newsCreatedDate
select new NewsListViewModel
{
NewsCreatorFName = n.Profile.profileFirstName,
NewsCreatorLName = n.Profile.profileLastName,
NewsID = n.newsID,
NewsCreatorID = n.userID,
NewsTitle = n.newsTitle,
CreatedDate = n.newsCreatedDate
});
return View(await model.ToListAsync());
}
}

Resources