public static Person FindBestMatch(IImportingPerson source) { var matches = FindMatches(source).ToList(); return((from match in matches let score = GetMatchScore(source, match) where score < 2 orderby score select match).FirstOrDefault()); }
static IEnumerable <Person> ByImportedPayments(IImportingPerson source) { if (string.IsNullOrEmpty(source.FinalFour)) { return(Enumerable.Empty <Person>()); } return(AppFramework.Table <Payment>().Rows .Where(p => p.Method == "Credit Card" && p.CheckNumber == source.FinalFour) .Select(p => p.Person) .Where(p => GetMatchScore(source, p) == 0)); }
static IEnumerable <Person> ByEmail(IImportingPerson source) { if (string.IsNullOrEmpty(source.Email)) { yield break; } var email = AppFramework.Table <EmailAddress>().Rows .FirstOrDefault(e => e.Email.Equals(source.Email, StringComparison.OrdinalIgnoreCase)); if (email?.Person != null) { yield return(email.Person); } }
static IEnumerable <Person> ByPhone(IImportingPerson source) { var phone = source.Phone.FormatPhoneNumber(); if (string.IsNullOrEmpty(phone)) { yield break; } var match = AppFramework.Table <Person>().Rows.FirstOrDefault(p => p.Phone == phone); if (match != null && GetMatchScore(source, match) == 0) { yield return(match); } }
static IEnumerable <Person> Fuzzy(IImportingPerson source) { IEnumerable <Person> candidates = AppFramework.Table <Person>().Rows; // Filter by each field, but only if that field has any matches. if (!string.IsNullOrEmpty(source.Address)) { var sourceAddress = AddressInfo.Parse(source.Address); var sourceState = UsStates.Abbreviate(source.State); candidates = candidates.Where(p => IsMatch(p.Zip, source.Zip) && IsMatch(p.State, sourceState) && IsMatch(p.City, source.City) && AddressInfo.Parse(p.Address) == sourceAddress) .DefaultIfEmpty(candidates); } candidates = candidates.Where(p => p.LastName.Equals(source.LastName, StringComparison.CurrentCultureIgnoreCase)) .DefaultIfEmpty(candidates); if (!string.IsNullOrWhiteSpace(source.LastName)) { candidates = candidates.LevenshteinDistanceOf(p => p.LastName).ComparedTo(source.LastName) .BestMatches() .DefaultIfEmpty(candidates); } // Match the imported first name against either HisName or HerName. if (!string.IsNullOrWhiteSpace(source.FirstName)) { candidates = candidates.LevenshteinDistanceOf(p => p.HisName).ComparedTo(source.FirstName) .Union(candidates.LevenshteinDistanceOf(p => p.HerName).ComparedTo(source.FirstName)) .BestMatches() .Distinct() .DefaultIfEmpty(candidates); } // If none of the matches found anything, give up. if (candidates == AppFramework.Table <Person>().Rows) { return(Enumerable.Empty <Person>()); } return(candidates); }
public static int GetMatchScore(IImportingPerson source, Person match) { if (string.IsNullOrWhiteSpace(source.Address)) { return(String.Equals(source.LastName, match.LastName, StringComparison.CurrentCultureIgnoreCase) && String.Equals(source.FirstName, match.HisName, StringComparison.CurrentCultureIgnoreCase) ? 1 : 2); } if (!string.IsNullOrWhiteSpace(source.City) && !string.IsNullOrWhiteSpace(match.City) && !source.City.Equals(match.City, StringComparison.CurrentCultureIgnoreCase)) { return(2); } if (AddressInfo.Parse(source.Address) != AddressInfo.Parse(match.Address) || LevenshteinProcessor.LevenshteinDistance(source.LastName, match.LastName) > 1) { return(2); } return(0); }
public static IEnumerable <Person> FindMatches(IImportingPerson source) { return(all.Select(f => f(source).ToList()) .FirstOrDefault(Enumerable.Any) ?? Enumerable.Empty <Person>()); }