Преобразуйте строки из средства чтения данных во введенные результаты

для массивов с такими отверстиями [,2,,4,,6,7,,], потому что моя проблема заключалась в заполнении этих отверстий. Поэтому я изменил его в соответствии с моей потребностью:)

для меня работало следующее модифицированное решение:)

var arr = [,2,,4,,6,7,,]; //example
while(arr.length < 9){
  var randomnumber=Math.floor(Math.random()*9+1);
  var found=false;
  for(var i=0;i<arr.length;i++){
    if(arr[i]==randomnumber){found=true;break;}
  }

  if(!found)
    for(k=0;k<9;k++)
    {if(!arr[k]) //if it's empty  !!MODIFICATION
      {arr[k]=randomnumber; break;}}
}

alert(arr); //outputs on the screen
27
задан Anthony 29 July 2009 в 20:46
поделиться

4 ответа

Вам действительно нужен список, или IEnumerable будет достаточно хорош?

Я знаю, что вы хотите, чтобы он был общим, но гораздо более распространенным шаблоном является использование статического метода Factory на тип целевого объекта, который принимает строку данных (или IDataRecord). Это будет выглядеть примерно так:

public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }

    public static Employee Create(IDataRecord record)
    {
        return new Employee
        {
           Id = record["id"],
           Name = record["name"]
        };
    }
}

.

public IEnumerable<Employee> GetEmployees()
{
    using (var reader = YourLibraryFunction())
    {
       while (reader.Read())
       {
           yield return Employee.Create(reader);
       }
    }
}

Тогда, если вам действительно нужен список, а не IEnumerable, вы можете вызвать .ToList () по результатам. Я полагаю, вы могли бы также использовать дженерики + делегат, чтобы сделать код этого шаблона более пригодным для повторного использования.

Обновление: Я снова увидел это сегодня, и мне захотелось написать общий код:

public IEnumerable<T> GetData<T>(IDataReader reader, Func<IDataRecord, T> BuildObject)
{
    try
    {
        while (reader.Read())
        {
            yield return BuildObject(reader);
        }
    }
    finally
    {
         reader.Dispose();
    }
}

//call it like this:
var result = GetData(YourLibraryFunction(), Employee.Create);
62
ответ дан 28 November 2019 в 04:12
поделиться

Как Волшебство

я лично ОЧЕНЬ НЕ ХОЧУ делать ручное отображение в конструкторах, я - также не поклонник выполнения моего собственного отражения. Таким образом, вот другая любезность решения замечательного (и довольно повсеместна) lib Newtonsoft JSON.

Это будет только работать, если Ваши имена свойства точно будут соответствовать datareader именам столбцов, но это работало хорошо на нас.

... предполагает, что у Вас есть имя datareader "yourDataReader"...

        var dt = new DataTable();
        dt.Load(yourDataReader);
        // creates a json array of objects
        string json = Newtonsoft.Json.JsonConvert.SerializeObject(dt);
        // this is what you're looking for right??
        List<YourEntityType> list = 
Newtonsoft.Json.JsonConvert
.DeserializeObject<List<YourEntityType>>(json);
0
ответ дан 28 November 2019 в 04:12
поделиться

Хотя я бы не рекомендовал это для производственного кода, но вы можете сделать это автоматически, используя отражение и универсальные типы:

public static class DataRecordHelper
{
    public static void CreateRecord<T>(IDataRecord record, T myClass)
    {
        PropertyInfo[] propertyInfos = typeof(T).GetProperties();

        for (int i = 0; i < record.FieldCount; i++)
        {
            foreach (PropertyInfo propertyInfo in propertyInfos)
            {
                if (propertyInfo.Name == record.GetName(i))
                {
                    propertyInfo.SetValue(myClass, Convert.ChangeType(record.GetValue(i), record.GetFieldType(i)), null);
                    break;
                }
            }
        }
    }
}

public class Employee
{
    public int Id { get; set; }
    public string LastName { get; set; }
    public DateTime? BirthDate { get; set; }

    public static IDataReader GetEmployeesReader()
    {
        SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString);

        conn.Open();
        using (SqlCommand cmd = new SqlCommand("SELECT EmployeeID As Id, LastName, BirthDate FROM Employees"))
        {
            cmd.Connection = conn;
            return cmd.ExecuteReader(CommandBehavior.CloseConnection);
        }
    }

    public static IEnumerable GetEmployees()
    {
        IDataReader rdr = GetEmployeesReader();
        while (rdr.Read())
        {
            Employee emp = new Employee();
            DataRecordHelper.CreateRecord<Employee>(rdr, emp);

            yield return emp;
        }
    }
}

Затем вы можете использовать CreateRecord () для создания экземпляра любого класса из полей в средстве чтения данных.

<asp:GridView ID="GvEmps" runat="server" AutoGenerateColumns="true"></asp:GridView>

GvEmps.DataSource = Employee.GetEmployees();
GvEmps.DataBind();
3
ответ дан 28 November 2019 в 04:12
поделиться

Вы можете создать метод расширения, например:

public static List<T> ReadList<T>(this IDataReader reader, 
                                  Func<IDataRecord, T> generator) {
     var list = new List<T>();
     while (reader.Read())
         list.Add(generator(reader));
     return list;
}

, и использовать его примерно так:

var employeeList = reader.ReadList(x => new Employee {
                                               Name = x.GetString(0),
                                               Age = x.GetInt32(1)
                                        });

Предложение Джоэла хорошее. Вы можете вернуть IEnumerable . Приведенный выше код легко преобразовать:

public static IEnumerable<T> GetEnumerator<T>(this IDataReader reader, 
                                              Func<IDataRecord, T> generator) {
     while (reader.Read())
         yield return generator(reader);
}

Если вы хотите автоматически сопоставить столбцы со свойствами, идея кода такая же. Вы можете просто заменить функцию generator в приведенном выше коде на функцию, которая опрашивает typeof (T) и устанавливает свойства объекта, используя отражение, считывая совпадающий столбец. Однако я лично предпочитаю определять фабричный метод (например, тот, который упоминается в ответе Джоэла) и передавать его делегат в эту функцию:

 var list = dataReader.GetEnumerator(Employee.Create).ToList();
24
ответ дан 28 November 2019 в 04:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: