Come faccio ad architettare il codice postale e la funzionalità di calcolo della distanza?

1

Sto costruendo un'app utilizzando MVC 4 / Razor e EF 4 / .NET 4 in cui è possibile cercare elementi per codice di avviamento postale e recuperare così gli elementi solo a una certa distanza dal codice postale corrente. Ho una classe che calcola la distanza utilizzando i file del registro geografico (zip, lat e lon) e la formula di Haversine .

Il mio problema specifico riguarda la parte SQL del mio codice. Ho una vista che utilizza un cercapersone (20 risultati per pagina) e ha collegamenti ipertestuali che ordinano le colonne in ordine asc e desc. Ho anche 3 elenchi a discesa che possono ulteriormente filtrare i risultati in basso: Produttore, Categoria, Distanza.

Quando sto filtrando per dire 50 miglia, la mia classe recupera un IEnumerable di codici postali che si trovano all'interno della distanza richiesta. A volte questo può essere nell'area da 10.000 a 30.000. Ogni oggetto Item contiene un int ZipCode

IlproblemacheEFgeneraquandoprovoadafferrareoggettidaldatabaseusandounelencodicodicipostaliaccettabilièUnadelletuequeryètroppoprofondamenteannidata.Provaaromperli.Presumochesiaperchénonpuoiavereunaclausolawhereconmigliaiadicondizioni.Questohasenso.Hotrovatouncollegamentoalcunigiornifachefondamentalmentesioccupavadicreareunatabellatemporaneadautilizzarecomeelenconellacondizionewhere,manonriescepiùatrovareillink.SiapplicavaanchearawADO.NETanzichéaEF.

Lamiadomandaèfondamentalmente,comepossoimplementarelafunzionalitàchedesiderosenzaapportaremodificheenormi?

using(varcontext=newJDMExchangeEntities()){varresults=context.Items.Include(P=>P.Manufacturer).Include(P=>P.Category).Include(P=>P.VehicleMake).Include(P=>P.VehicleModel).Include(P=>P.VehicleYear);//Categorylogicif(!string.IsNullOrEmpty(Categories)){results=results.Where(P=>P.Category.Name==Categories);}//Manufacturerslogicif(!string.IsNullOrEmpty(Manufacturers)){results=results.Where(P=>P.Manufacturer.Name==Manufacturers);}//Vehiclelogicif(Vehicle>0){results=results.Where(P=>P.YearId==Vehicle);}if(acceptableCodes.Count>0){List<int>codes=acceptableCodes.Keys.ToList();results=results.Where(P=>codes.Contains((int)P.ZipCode));//return_UoW.tblcoursebookingRepo.All//.Where(cb=>AttendanceIDs.Contains(cb.Attended))//.ToList();}////TakeoutitemsthatarenotintheManualQueryResultsDictionary//if(!String.IsNullOrEmpty(ManualQuery))//{//varall=listB.Where(b=>listA.Any(a=>a.code==b.code));//results=results.Where(r=>ManualQueryResults.Any(a=>a==r.id));//}////TakeoutzipsnotinthecloseCodesvariable//if(!string.IsNullOrEmpty(DistanceLimit))//{//results=results.Where(P=>closeCodes.Any(z=>z.ZipCode.Code==P.ZipCode));//}switch(sortOrder){case"Price_desc":
                    results = results.OrderByDescending(P => P.Price);
                    break;
                case "Price":
                    results = results.OrderBy(P => P.Price);
                    break;
                case "Date_asc":
                    results = results.OrderBy(P => P.PostDate);
                    break;
                default:
                    results = results.OrderByDescending(P => P.PostDate);
                    break;

            }
            int pageSize = 20;
            int pageNumber = (page ?? 1);


            IPagedList<Item> cc = results.ToPagedList(pageNumber, pageSize);

Potrei chiamare .ToList() da qualche parte prima di colpire il .ToPagedList() , ma poi tornerò indietro di migliaia di voci e quindi ritarderò il tempo di risposta di alcuni secondi.

Dopo ho potuto facilmente creare un elenco a pagine dall'elenco IEnumerable. Voglio provare a ridurre al minimo i tempi di risposta e quindi penso che l'area che devo correggere sia nel codice SQL in modo da non estrarre dati non necessari e quindi filtrarli.

    
posta Adrian 16.01.2014 - 03:03
fonte

1 risposta

9

Effettuare qualsiasi lavoro geospaziale in SQL Server senza utilizzare i tipi geospaziali è, francamente, folle.

Memorizza il codice postale se vuoi come riferimento , ma esegui query in base a latitudine e longitudine utilizzando geografia tipo. Ha anche una funzione STDistance che può utilizzare un indice geospaziale per restituire risultati in tempo costante .

Sì, ciò implica probabilmente le cosiddette modifiche "enormi". Fallo. Ho visto sistemi di ricerca implementati usando l'approccio che stai cercando di usare e sono, francamente, orribili. È così semplice fare una ricerca con raggio vero in questi giorni, stai facendo a te stesso e ai tuoi utenti un grave disservizio per hackerare insieme una versione semi-assed come questa.

Inoltre, i codici postali sono numerici? Ovviamente stai solo pensando che questo sia usato negli Stati Uniti, ma anche così ... ottimo modo per assicurare un dolore estremo se hai bisogno o vuoi globalizzare.

    
risposta data 16.01.2014 - 04:30
fonte

Leggi altre domande sui tag