Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何改进从用户配置文件对象获取过滤数据的方法?_C#_.net_Linq_Linq To Sql_Asp.net Membership - Fatal编程技术网

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

C# 如何改进从用户配置文件对象获取过滤数据的方法?,c#,.net,linq,linq-to-sql,asp.net-membership,C#,.net,Linq,Linq To Sql,Asp.net Membership,我已经破解了以下代码,从我用户的个人资料数据中获得了一些细节。它能工作,但不漂亮 我有一个UserPreferences对象,它保存在用户配置文件中。它具有是否需要SMS警报消息以及警报类型的属性。短信将作为电子邮件发送。创建警报时,我希望获取一个以逗号分隔的地址字符串,该字符串应针对该警报类型得到通知 用户拥有手机号码和运营商。运营商有一个类似{number}@{domain}的SMS电子邮件格式,我正在用用户的号码和运营商的域替换这些字段 正如我所说,这确实有效,但我不在乎它是两种方法,也不

我已经破解了以下代码,从我用户的个人资料数据中获得了一些细节。它能工作,但不漂亮

我有一个UserPreferences对象,它保存在用户配置文件中。它具有是否需要SMS警报消息以及警报类型的属性。短信将作为电子邮件发送。创建警报时,我希望获取一个以逗号分隔的地址字符串,该字符串应针对该警报类型得到通知

用户拥有手机号码和运营商。运营商有一个类似{number}@{domain}的SMS电子邮件格式,我正在用用户的号码和运营商的域替换这些字段

正如我所说,这确实有效,但我不在乎它是两种方法,也不在乎它看起来有多混乱。有没有一种更简洁的方法可以将此作为一种方法来编写

更新:我已经重构了我的prefs查询,以减少GetProfile的重复使用,如下所示:

Mh,这个怎么样:

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查询并不一定是最好的做法

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

也许这是最好的了。您认为这段代码可以从使用SelectMany anywhere中获益吗?取决于您对益处的定义。这种方式的代码非常清楚:首先获取所有用户偏好,这些偏好希望通过SMS针对特定警报发出警报,然后根据模板构建实际地址。现在你也许可以用SelectMany将它全部拉到一个Linq链中,但我怀疑是否有人在6个月后重新使用它,他会立即理解它的实际用途。多么有趣,直到我自己做了这件事之后,我才意识到你已经改变了选择的顺序和位置。迟来的道具。Id和MobileCarried的类型是什么?然后你可以只使用c.Id==p.mobileCarried,和SendAlertToSMS==true&&。。或者只发送AlertTosms&&。。。Equalsobject不是一个很好的方法use@abatishchev:谢谢,我会在实际代码中更改它。我可能使用Equals只是因为它看起来更干净,读起来更好。好的,只是一个注释。很好,如果我们现在都说:啊,很好-没有更多的循环!如果我以后想像First-Last那样格式化地址,这种方法似乎更灵活或更容易遵循。谢谢你,先生。我在想我是否真的需要在那里进行区分,但我意识到两个用户可能出于某种奇怪的原因,因为没有什么阻止它输入同一个手机号码,这将有助于确保每个号码只发送一次信息。@Justin:您可以区分偏好和结果。我更新了我的答案。在我看来,第二种方法更可靠,可读性更强。
var prefs = Membership.GetAllUsers()
              .OfType<MembershipUser>()
              .Select(u => WebProfile.GetProfile(u.UserName).Preferences)
              .Where(p => p.SendAlertsToSMS && p.SMSAlertTypeIds.Contains(alertTypeId));
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);
}
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());