Проход по значениям полей LINQ - PullRequest
0 голосов
/ 25 марта 2009

У меня есть текстовый файл с заполнителями, такими как:

Спасибо за ваш заказ [OrderNo]. Ваш заказ будет отправлен по адресу: [Название] [Street1] [Street2] и т. Д.

Заполнителями являются имена полей в базе данных, заключенные в квадратные скобки.

Я хочу получить одну запись из базы данных, например:

var order = (из o в testContext.OrderTables, где o.OrderID == id select o) .Single ();

Тогда я бы хотел иметь возможность перебрать объект заказа и получить имя поля и его значение для заполнения заполнителя.

Возможно ли это?

Ответы [ 5 ]

2 голосов
/ 19 ноября 2011

Для тех, кто ищет решение, у меня получилось получить список писем:

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 голосов
/ 25 марта 2009

Конечно. Ничто в структуре не поддерживает это, как бы то ни было. Вам нужно будет выполнить поиск по тегам, а затем использовать отражение для доступа к соответствующим свойствам в вашем объекте Order.

Другой, более простой способ (без размышлений) - сбросить ваш ордер в хеш-таблицу ... Вот некоторый псевдокод, который на самом деле может работать как есть:

var hashy = 
  (from o in Orders where o.Id = id select 
  new Dictionary<string,object>{ {"Id", o.Id}, 
     {"Name",o.Name}, /*yadda*/}).Single();

На данный момент все, что вам нужно сделать, это получить строку из вашего текстового файла и индексировать ее в хеш.

Очевидно, что 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()

Это не так элегантно, потому что вы отключаете вызов Linq через ToArray (), который отзовет все ордера. В конце концов, вероятно, лучше всего вытащить ваш заказ, поместить необходимую информацию в хеш, а затем обработать ваш текстовый файл. Вам придется перекомпилировать, если ваша база данных изменится; опять же, это не так элегантно, как моя первая попытка ...

1 голос
/ 25 марта 2009

Вы не можете использовать 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 );
    }
}
1 голос
/ 25 марта 2009

Вы можете сделать это с помощью .GetType (), а затем использовать отражение, чтобы получить отдельные свойства и их значения.

0 голосов
/ 25 марта 2009

Как насчет этого:


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

Я не уверен, нравится ли мне это, но это работает. : -)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...