C# 如何改进从用户配置文件对象获取过滤数据的方法?
我已经破解了以下代码,从我用户的个人资料数据中获得了一些细节。它能工作,但不漂亮 我有一个UserPreferences对象,它保存在用户配置文件中。它具有是否需要SMS警报消息以及警报类型的属性。短信将作为电子邮件发送。创建警报时,我希望获取一个以逗号分隔的地址字符串,该字符串应针对该警报类型得到通知 用户拥有手机号码和运营商。运营商有一个类似{number}@{domain}的SMS电子邮件格式,我正在用用户的号码和运营商的域替换这些字段 正如我所说,这确实有效,但我不在乎它是两种方法,也不在乎它看起来有多混乱。有没有一种更简洁的方法可以将此作为一种方法来编写 更新:我已经重构了我的prefs查询,以减少GetProfile的重复使用,如下所示: Mh,这个怎么样:C# 如何改进从用户配置文件对象获取过滤数据的方法?,c#,.net,linq,linq-to-sql,asp.net-membership,C#,.net,Linq,Linq To Sql,Asp.net Membership,我已经破解了以下代码,从我用户的个人资料数据中获得了一些细节。它能工作,但不漂亮 我有一个UserPreferences对象,它保存在用户配置文件中。它具有是否需要SMS警报消息以及警报类型的属性。短信将作为电子邮件发送。创建警报时,我希望获取一个以逗号分隔的地址字符串,该字符串应针对该警报类型得到通知 用户拥有手机号码和运营商。运营商有一个类似{number}@{domain}的SMS电子邮件格式,我正在用用户的号码和运营商的域替换这些字段 正如我所说,这确实有效,但我不在乎它是两种方法,也不
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());