Как я могу улучшить свой метод получения отфильтрованных данных из объектов профиля пользователя? - PullRequest
1 голос
/ 08 апреля 2011

Я взломал следующий код вместе, чтобы получить некоторые данные из данных профиля моих пользователей. Это работает, но не красиво.

У меня есть UserPreferences объект, который сохраняется в профилях пользователей.У этого есть свойства для того, желательны ли сообщения оповещения SMS и для каких типов оповещений.SMS будет отправлено по электронной почте.Когда создается оповещение, я хочу получить разделенную запятыми строку адресов, которые должны получать уведомления для этого типа оповещения.

У пользователя есть номер мобильного телефона и оператор связи.У операторов есть формат SMS-сообщения, такой как "{number}@ {domain}, и я заменяю эти поля номером пользователя и доменом оператора.

Как я уже сказал, это работает, но Я не знаюне важно, что это два метода или насколько грязно это выглядит. Есть ли более компактный способ записать это как один метод?

public static string GetSMSAlertSubscribers(int alertTypeId) {
  // end result I want is like: "1234567890@vtext.com,0987654321@text.att.net"
  return String.Join(",", GetSMSAlertSubscribersEnumerable(alertTypeId));
}

public static IEnumerable<string> GetSMSAlertSubscribersEnumerable(int alertTypeId) {
  var prefs = Membership.GetAllUsers()
                        .Cast<MembershipUser>()
                        .Where(u => WebProfile.GetProfile(u.UserName).Preferences.SendAlertsToSMS.Equals(true)
                                 && WebProfile.GetProfile(u.UserName).Preferences.SMSAlertTypeIds.Contains(alertTypeId))
                        .Select(u => WebProfile.GetProfile(u.UserName).Preferences);

  var carriers = new AlertRepository().FindAllMobileCarriers().ToList();

  foreach (UserPreferences p in prefs) {
    yield return carriers.Where(c => c.Id.Equals(p.MobileCarrierId))
                         .Select(c => c.SMSEmailAddressFormat.Replace("{domain}", c.SMSEmailAddressDomain).Replace("{number}", p.MobileNumber))
                         .SingleOrDefault();
  }
}

Я бы назвал его так:

var emailTo = GetSMSAlertSubscribers(3);

ОБНОВЛЕНИЕ: Я реорганизовал свой запрос "prefs", чтобы уменьшить количество повторяющихся попыток использования GetProfile() как:

var prefs = Membership.GetAllUsers()
              .OfType<MembershipUser>()
              .Select(u => WebProfile.GetProfile(u.UserName).Preferences)
              .Where(p => p.SendAlertsToSMS && p.SMSAlertTypeIds.Contains(alertTypeId));

Ответы [ 2 ]

2 голосов
/ 09 апреля 2011
var q = from x in
            (from p in prefs
            from c in carriers
            where p.MobileCarrierId == c.Id
            select new
            {
                c.SMSEmailAddressFormat,
                c.SMSEmailAddressDomain,
                p.MobileNumber
            }).Distinct()
        select x.SMSEmailAddressFormat
            .Replace("{domain}", x.SMSEmailAddressDomain)
            .Replace("{number}", x.MobileNumber);

return String.Join(", ", q);

var q = from p in prefs
        from c in carriers
        where p.MobileCarrierId == c.Id
        select c.SMSEmailAddressFormat
           .Replace("{domain}", c.SMSEmailAddressDomain)
           .Replace("{number}", p.MobileNumber);

return String.Join(", ", q.Distinct());
1 голос
/ 08 апреля 2011

М-ч, как на счет этого:

var prefs = Membership
                .GetAllUsers()
                .OfType<MembershipUser>()
                .Select(u => WebProfile.GetProfile(u.UserName).Preferences)
                .Where(p => SendAlertToSMS.Equals(true) && SMSAlertTypeIds.Contains(alertTypeId));

var carriers = new AlertRepository().FindAllMobileCarriers().ToList();

foreach (UserPreferences p in prefs) 
{
    var carrier = carriers.FindOrDefault(c => c.Id.Equals(p.MobileCarrierId));
    yield return PopulateAddress(c, p);
}

И сделать замену в PopulateAddress.Выглядит менее грязно для меня сейчас.Объединение всего в один запрос Linq не обязательно является лучшим решением.

...