Контекст Entity Framework SqlQuery <T>для хранимой процедуры возвращает SqlParameter уже содержится в другой SqlParameterCollection - PullRequest
0 голосов
/ 10 января 2019

Мне нужно переместить фильтрацию сложного объекта из Linq в SQL в хранимую процедуру, потому что мне нужно загрузить данные в память, чтобы применить некоторые фильтры с помощью ToList (). Запрос Linq вызывает тайм-аут некоторых поисков. Когда я переключился на хранимую процедуру, я изменил функцию следующим образом:

    private IQueryable<ProposalLogVM> ApplyProposalSearch(IndexSearchVM search)
    {
        SqlParameter YearCode;
        SqlParameter ProposalStatus;
        SqlParameter Company;
        SqlParameter SearchString;

        if (!String.IsNullOrWhiteSpace(search.SearchString) && search.Year == null)
        {
            search.Year = DateTime.Now.Year;
        }

        if (!String.IsNullOrWhiteSpace(search.Year.ToString()))
        {
            YearCode = new SqlParameter("@Year", search.Year.ToString());
        }
        else
        {
            YearCode = new SqlParameter("@Year", DBNull.Value);
        }

        if (!String.IsNullOrWhiteSpace(search.ProposalStatus))
        {
            ProposalStatus = new SqlParameter("@ProposalStatus", search.ProposalStatus);
        }
        else
        {
            ProposalStatus = new SqlParameter("@ProposalStatus", DBNull.Value);
        }

        if (!String.IsNullOrWhiteSpace(search.CompanyID.ToString()))
        {
            Company = new SqlParameter("@CompanyID", search.CompanyID.ToString());
        }
        else
        {
            Company = new SqlParameter("@CompanyID", DBNull.Value);
        }

        if (!String.IsNullOrWhiteSpace(search.SearchString))
        {
            SearchString = new SqlParameter("@SearchString", search.SearchString);
        }
        else
        {
            SearchString = new SqlParameter("@SearchString", DBNull.Value);
        }

        var proposals = _dbpm.Database.SqlQuery<ProposalLogVM>("EXEC spSearchProposals @Year, @ProposalStatus, @CompanyID, @SearchString", YearCode, ProposalStatus, Company, SearchString).AsQueryable();

        switch (search.SortOption)
        {
            case "ProposalNumber":
                proposals = proposals.OrderBy(p => p.ProposalNumber);
                break;
            case "ProjectName":
                proposals = proposals.OrderBy(p => p.ProjectName);
                break;
            case "ProjectNameD":
                proposals = proposals.OrderByDescending(p => p.ProjectName);
                break;
            case "BidDate":
                proposals = proposals.OrderBy(p => p.BidDate);
                break;
            case "BidDateD":
                proposals = proposals.OrderByDescending(p => p.BidDate);
                break;
            case "Owner":
                proposals = proposals.OrderBy(p => p.Owner);
                break;
            case "OwnerD":
                proposals = proposals.OrderByDescending(p => p.Owner);
                break;
            default:
                proposals = proposals.OrderByDescending(p => p.ProposalNumber);
                break;
        }

        return proposals;

    }

Теперь я получаю «SqlParameter уже содержится в другой SqlParameterCollection». при выполнении строки

        // get the raw proposal list, but don't execute or copy to memory
        IQueryable<ProposalLogVM> rawProposals = ApplyProposalSearch(viewModel.Search);

        // Allow ToPagedList() to do the hard work
        viewModel.Proposals = rawProposals.ToPagedList((int)viewModel.Search.Page, (int)viewModel.Search.Lines);

Если я просто выполню строку:

        var proposals = _dbpm.Database.SqlQuery<ProposalLogVM>("spSearchProposals @Year, @ProposalStatus, @CompanyID, @SearchString", YearCode, ProposalStatus, Company, SearchString).AsQueryable().ToList();

Он работает нормально и возвращает все 390 000 ожидаемых записей.

Я провел последние несколько часов, читая все остальные статьи о переполнении стека и пробуя эти решения, но ни одна из них, похоже, не работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...