开发者

How can I improve my method to get filtered data from user profile objects?

开发者 https://www.devze.com 2023-02-22 17:23 出处:网络
I\'ve hacked the following code together to get some details from my users\' profile data. It works, but isn\'t pretty.

I've hacked the following code together to get some details from my users' profile data. It works, but isn't pretty.

I have a UserPreferences object that is saved in the users' profiles. It has properties for whether SMS alert messages are desired and for which alert types. The SMS will be sent as an email. When an alert is created, I want to get a comma-delimited string of the addresses that should get notified for that alert type.

The user has a mobile number and a carrier. The carriers have an SMS email format like "{number}@ {domain} and I'm replacing those fields with the user's number and the carrier's domain.

As I said, this does work, but I don't care for it being two methods or how messy it seems. Is there a more compact way of writing this as one method?

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 => WebProf开发者_如何学运维ile.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();
  }
}

I'd call it like:

var emailTo = GetSMSAlertSubscribers(3);

UPDATE: I've refactored my "prefs" query to reduce the repetitive use of GetProfile() as:

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


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());


Mh, how about this:

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);
}

And do the replace stuff in PopulateAddress. Looks less messy to me now. Cramming everything into one Linq query is not neccessarily the best thing to do.

0

精彩评论

暂无评论...
验证码 换一张
取 消