简体   繁体   中英

how to optimize a linq query c# complex object?

I am making a method that returns me the visitor's data, make this query with linq c #, which is the following,

public async Task<Models.Visitor> GetVisitorByEmail(string email)
{
    return (from v in _unitOfWorkModel.Repository<Visitor>().GetList()
            where v.Email.ToLower() == email.ToLower()
            select new Models.Visitor
            {
                VisitorId = v.VisitorId,
                FirstName = v.FirstName,
                SecondName = v.SecondName,
                FirstLastName = v.FirstLastName,
                SecondLastName = v.SecondLastName,
                Gender = (from g in _unitOfWorkModel.Repository<Gender>().GetList()
                          where g.GenderId == v.GenderId
                          select new Models.Gender
                          {
                              GenderId = g.GenderId,
                              GenderName = g.GenderName,
                          }).FirstOrDefault(),
                Email = v.Email,
                Telephone = v.Telephone,
                Family = (from vf in _unitOfWorkModel.Repository<VisitorFamily>().GetList()
                          join f in _unitOfWorkModel.Repository<Family>().GetList()
                          on vf.FamilyId equals f.FamilyId
                          where vf.VisitorId == v.VisitorId
                          select new Models.Family
                          {
                              FamilyId = f.FamilyId,
                              FamilyName = f.FamilyName,
                              PhotoPath = f.PhotoPath
                          }).ToList(),
                Territory = (from vt in _unitOfWorkModel.Repository<VisitorTerritory>().GetList()
                             join t in _unitOfWorkModel.Repository<Territory>().GetList()
                             on vt.TerritoryId equals t.TerritoryId
                             where vt.VisitorId == v.VisitorId
                             select new Models.Territory
                             {
                                 TerritoryId = t.TerritoryId,
                                 TerritoryName = t.TerritoryName,
                                 Axis = (from a in _unitOfWorkModel.Repository<Axis>().GetList()
                                         where a.AxisId == t.AxisId
                                         select new Models.Axis
                                         {
                                             AxisId = a.AxisId,
                                             AxisName = a.AxisName,
                                         }).FirstOrDefault(),
                             }).ToList(),
                IsActive = v.IsActive,
                PhotoPath = v.PhotoPath,
                UserTypeId = v.UserTypeId,
                UserId = v.UserId,
                CreateBy = v.CreateBy,
                CreationDate = v.CreationDate,
                ModifiedBy = v.ModifiedBy,
                ModifiedDate = v.ModifiedDate,
            }).FirstOrDefault();
}

I would like to know if I have 20 visitors for example, if the api that I am developing will give me good response times or is there another more optimal way to do it, since I am new to creating complex objects with linq c #, I am using ASP.NET CORE 3.1 and Core Entity Framework,

I would appreciate the help to optimize this query you made.

I am attentive to your suggestions

Here is the example of style in which you must attach all nested entities:

public Task<IQueryable<Models.Gender>> GetGenderById(int id)
{
    return _unitOfWorkModel.Repository.Get<Gender>(x => x.GenderId = id).
}

In this example you're passing query on SQL server and return result in one record by ToList() (in GetVisitorByEmail() method).

Get() method must be in your base repository by default and all yours repos must inherit it with passing it's entity type to:

public abstract class BaseRepository<T> : IBaseRepository<T> where T : class
    {
        protected readonly ApplicationDbContext DbContext;
        protected readonly DbSet<T> DbSetEntity;
        private readonly ILogger<BaseRepository<T>> _logger;

        protected BaseRepository(ApplicationDbContext dbContext,ILoggerFactory loggerFactory)
        {
            DbContext = dbContext;
            DbSetEntity = DbContext.Set<T>();

            _logger = loggerFactory.CreateLogger<BaseRepository<T>>();
        }

        ...

        public virtual T Get(Expression<Func<T, bool>> predicate)
        {
            return DbContext.Set<T>().FirstOrDefault(predicate);
        }

And use this method:

return (from v in _unitOfWorkModel.Repository<Visitor>
            where v.Email.ToLower() == email.ToLower()
            select new Models.Visitor
            {
                VisitorId = v.VisitorId,
                FirstName = v.FirstName,
                SecondName = v.SecondName,
                FirstLastName = v.FirstLastName,
                SecondLastName = v.SecondLastName,
                Gender = GetGenderById(v.GenderId).ToList(),
                Email = v.Email
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM