如何改进我的方法以从用户配置文件对象中获取过滤数据?

时间:2011-04-07 21:58:01

标签: c# .net linq linq-to-sql asp.net-membership

我一起攻击了以下代码,以便从用户的个人资料数据中获取一些细节。 它有效但不漂亮。

我有一个UserPreferences对象保存在用户的个人资料中。它具有是否需要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 个答案:

答案 0 :(得分:2)

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 :(得分:1)

嗯,这个怎么样:

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查询中并不是最好的事情。