2017-01-20 2 views
0

У меня есть модель, которая имеет массив объектов как один из ее атрибутов. Например:Извлечение модели с объектом массива из хранимой процедуры в C#

class Person { 
int id; 
string name; 
int age; 
Work[] workExperiences; 
} 

class Work { 
int id; 
string address; 
string position; 
} 

Person and Work - это таблицы в базе данных. Как создать хранимую процедуру, чтобы я мог получить всю информацию в одном запросе?

ответ

0

Поскольку вы не указали, какой сервер базы данных вы используете или каким образом вы приближаетесь к базе данных (EntityFramework, различные OR/M, direct SqlConnection, ...) Я сделаю предположение вы используете MSSQL Server и SqlConnection.

Предположим, у вас очень простая хранимая процедура, называемая GetPersonAndWorkExperience, которая принимает PersonID в качестве аргумента.

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 

CREATE PROCEDURE GetPersonAndWorkExperience 
@PersonID INT 

AS 
BEGIN 
    SELECT 
     p.PersonID, 
     p.Name, 
     p.Age, 
     w.WorkID, 
     w.WorkAddress, 
     w.Position 
    FROM Person p 
    INNER JOIN Work w ON w.WorkID = p.PersonID 
    WHERE p.PersonID = @PersonID 
END 
GO 

Это вернет результирующий набор со всем необходимым.

Если вы приближаетесь к своей базе данных с помощью SqlConnection, вы можете вызвать хранимую процедуру и вернуть данные, используя классы моделей, как указано в вашем вопросе. Для удобства я преобразовываю массив в List<Work>. Я также переименовываю адрес в WorkAddress, потому что address является зарезервированным словом в SQL, и это плохая практика, чтобы назвать ваши столбцы как таковые.

public DataTable GetPersonAndWorkExperience(int personId) 
{ 
    string connectionString = ""; //load connection string here 
    DataTable result; 

    using (SqlConnection conn = new SqlConnection(connectionString)) 
    { 
     using (SqlCommand cmd = new SqlCommand("dbo.GetPersonAndWorkExperience")) 
     { 
      cmd.CommandType = CommandType.StoredProcedure; 
      cmd.Parameters.Add(new SqlParameter("@PersonID", personId)); 
      conn.Open(); 
      cmd.Connection = conn; 

      using (SqlDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection)) 
      { 
       result = new DataTable(); 
       result.Load(rdr); 
      } 
     } 
    } 

    return result; 
} 

Теперь у вас есть DataTable. Теперь вы можете сделать что-то вдоль линий

Person p = new Person 
{ 
    Id = int.Parse(dt.Rows[0].Columns["PersonID"]), 
    Name = dt.Rows[0].Columns["Name"]), 
    Age = int.Parse(dt.Rows[0].Columns["Age"]) 
}; 

p.WorkExperiences = new List<Work>(); 

List<Work> workExperiences = (from row in dt.AsEnumerable() 
          select new Work 
          { 
           Id = row.Field<int>("WorkID"), 
           WorkAddress = row.Field<string>("WorkAddress"), 
           Position = row.Field<string>("Position") 
          }).ToList(); 

p.WorkExperiences.AddRange(workExperiences); 

Пожалуйста, обратите внимание, что это свидетельствует о его сути и не может скомпилировать, как это было написано в текстовом редакторе, но вы получите идею.

О, если вы действительно хотите сохранить свой массив, вы можете его инициализировать с помощью подсчета строк DataTable.

+0

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

Смежные вопросы