我有一个带占位符的文本文件,例如:
感谢您的订单[OrderNo]。您的订单将发货至: [名称] [Street1] [Street2]等
占位符是数据库中用括号括起来的字段名称。
我想从数据库中检索单个记录,如:
var order =(来自testContext.OrderTables中的o,其中o.OrderID == id选择o).Single();
然后我希望能够遍历订单对象并获取字段名称,并且填充占位符是值。
这可能吗?
答案 0 :(得分:2)
不确定。但是,框架中没有任何内容支持这一点。您必须搜索标签,然后使用反射来访问Order对象中的相应属性。
<击> 另一种更简单的方法(没有反射)是将您的订单转储到哈希表中......这里有一些伪代码可能实际上按原样运行:
var hashy =
(from o in Orders where o.Id = id select
new Dictionary<string,object>{ {"Id", o.Id},
{"Name",o.Name}, /*yadda*/}).Single();
此时,您需要做的就是从文本文件中获取字符串并将索引编入您的hashy。
显然Linq to Sql不喜欢查询中的列表初始值设定项。您可以将它包装在方法调用中;我不确定。
稍加修改即可获得此工作版本:
var hashy =
(from o in Orders where o.Id = id select o).ToArray()
.Select(o=> new Dictionary<string,object>{{"Name",o.Name}})
.First()
它不那么优雅,因为你通过ToArray()绊倒Linq调用,这将撤回所有订单。最后,它最好只是提取您的订单,在哈希中填写您需要的信息,然后处理您的文本文件。如果数据库发生变化,您将不得不重新编译;再次,它不像我的第一次尝试那么优雅......
答案 1 :(得分:2)
对于任何寻找解决方案的人来说,这对我来说都是一个电子邮件列表:
Dim doc = From u In db.myTable, d In db.myTable2 _
Where u.UserId = d.UserId _
Select u.Email
If doc.Count > 0 Then
For Each rec In doc
strEmailBcc += rec & "; "
Next
Else
MsgBox("No e-mails were found.", MsgBoxStyle.Information, "E-mail Search")
End IF
答案 2 :(得分:1)
您可以使用.GetType()然后使用反射来获取各个属性及其值。
答案 3 :(得分:1)
您不能直接使用LINQ来遍历对象的属性,因为没有对象上可用对象的属性的枚举。但是,您可以使用Reflection来获取对象的属性。在查看这些内容时,LINQ可能会派上用场找到适合占位符的对象。
public Dictionary<string,object>
ValuesForPlaceHolders( object obj,
IEnumerable<string> placeHolders )
{
var map = new Dictionary<string,object>();
if (obj != null)
{
var properties = obj.GetType().GetProperties();
foreach (string placeHolder in placeHolders)
{
var property = properties.Where( p => p.Name == placeHolder )
.SingleOrDefault();
if (property != null)
{
map.Add( placeHolder, property.GetValue( obj, null ) );
}
}
}
return map;
}
编辑:编写上述示例是为了说明如何使用LINQ。我的偏好实际上是使用辅助方法来按名称获取值。请注意,下面的方法假定属性存在,但可以很容易地修改为在属性不存在时返回null。在我的使用中,我的调用是通过单元测试验证的,所以我不打扰额外的检查。
public static class TypeHelper
{
public static object GetPropertyValue( object obj, string name )
{
return obj == null ? null : obj.GetType()
.GetProperty( name )
.GetValue( obj, null );
}
}
答案 4 :(得分:0)
这个怎么样:
void Main()
{
var text = "Thank you for your order [OrderNo]. Your order will be shipped to: [Name] [Street1] [Street2]";
var order = new Order() {OrderNo = 1, Name="NameA", Street1 = "Address1A", Street2="Addres2A"};
var splitted = text.Split(']').ToList();
var orderType = (new Order()).GetType();
var newText = text;
splitted.ForEach(p =>
{
string field = p.Substring(p.IndexOf('[') + 1);
if (!string.IsNullOrEmpty(field))
{
var result = orderType.GetProperty(field).GetValue(order, null);
//var method = orderType.GetMethod("get_"+field);
//var result = method.Invoke(o, null);
newText = newText.Replace("[" + field + "]", result.ToString());
}
});
Console.WriteLine(newText);
}
public class Order
{
public Order()
{}
public int OrderNo {get; set;}
public string Name {get; set;}
public string Street1 {get; set;}
public string Street2 {get; set;}
}
我不确定我是否喜欢它,但确实有效。 : - )