Вернуть пользовательский объект <List T> из среды Entity и назначить источнику данных объекта - PullRequest
8 голосов
/ 27 октября 2011

Мне нужно руководство по проблеме, я использую Entity Framework 4.0, у меня есть DAL и BLL, и я привязываюсь к ObjectDataSource на странице.

Мне пришлось написать хранимую процедуру, используя PIVOT и динамический SQL, чтобы вернуть данные из нескольких объектов так, как я хочу.Теперь я пытаюсь выяснить, как я могу заставить Entity Framework возвращать пользовательский объект, который я могу связать с моим ObjectDataSource на странице, мне НУЖНО использовать пользовательский объект или динамический объект, поскольку хранимая процедура может возвращать любое числостолбцов, поэтому я не могу использовать строго типизированный класс или сущность, и мне нужно также иметь возможность связать это с ObjectDataSource.

Может кто-нибудь указать хороший способ сделать это и как определитьмоя функция?С некоторыми примерами кода, пожалуйста.

Я прочитал, что должен попытаться использовать List<T> для возврата объекта, так как EF не поддерживает возврат наборов данных / наборов данных, у меня пока есть следующее, но я знаю, что это не такправильно.

Я мало работал с дженериками, если бы вы могли указать, как это сделать, я уверен, что это будет полезно для многих людей.Пожалуйста, предоставьте примеры кода для функции и как связать ObjectDataSource с возвращаемым объектом?

Ваша помощь очень важна !!

Спасибо за вашу помощь, Ричард, именно так сейчас выглядит моя функция, основанная на вашем предложении использовать DbDataRecord

*Функция 1021 * C # для ObjectDataSource в DAL
public List<DbDataRecord> GetData(int product_id)
{
    List<DbDataRecord> availableProducts = new List<DbDataRecord>();

    var groupData = context.ExecuteStoreQuery<DbDataRecord>("exec 
  spGetProducts @ProductID={0}", product_id);

    availableProducts = groupData.ToList<DbDataRecord>();

    return availableProducts;
}

ObjectDataSource на странице ASPX

<asp:ObjectDataSource ID="ODSProductAvailability" runat="server"
        TypeName="Project.BLL.ProductBL" 
        SelectMethod="GetData"  >
     <SelectParameters>
        <asp:SessionParameter Name="product_id" SessionField="ProductID" />
     </SelectParameters>
</asp:ObjectDataSource>

Прямо сейчас я получаю эту ошибку при доступе к странице:

Тип результата 'System.Data.Common.DbDataRecord' может быть не абстрактным и должен включать конструктор по умолчанию

Это потому, что ExecuteStoreQuery ожидается, что будет определен класс или сущность?Как я могу просто создать объект на основе результатов хранимой процедуры и присвоить ему это?

Ответы [ 3 ]

4 голосов
/ 27 октября 2011

что-то вроде этого:

using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    string myQuery = @"SELECT p.ProductID, p.Name FROM 
        AdventureWorksEntities.Products as p";

    foreach (DbDataRecord rec in new ObjectQuery<DbDataRecord>(myQuery, context))
    {
        Console.WriteLine("ID {0}; Name {1}", rec[0], rec[1]);
    }
}
4 голосов
/ 27 октября 2011

Если у вас уже есть тип Entity, соответствующий вашему типу возврата proc, используйте его в качестве параметра типа.

public List<MyEntity> GetData<MyEntity>(int product_id) where T : class 
{

    List<MyEntity> myList = new List<MyEntity>(); 

    var groupData = context.ExecuteStoreQuery<MyEntity>("exec 
    spGetProductsByGroup @ProductID={0}", product_id);

    return myList;
}

В противном случае вы можете использовать ADO.NET DataReader для построениясписок вручную.

using (SqlConnection connection = new SqlConnection("your connection string"))
{
    SqlCommand command = new SqlCommand(
      "exec spGetProductsByGroup @ProductID",
      connection);
    command.Parameters.Add(product_id);

    connection.Open();

    SqlDataReader reader = command.ExecuteReader();

    List<ProcType> list = new List<ProcType>();
    if (reader.HasRows)
    {
        while (reader.Read())
        {
            list.Add(new ProcType(){Property1 = reader.GetInt32(0), Property1 = reader.GetString(1));
        }
    }
    reader.Close();

    return list;
}
0 голосов
/ 27 октября 2011

Если вы хотите представить результаты, скажем, в GridView, то на самом деле вы почти у цели - со столбцами связывания и AutoGenerate, потому что ObjectQuery является IEnumerable.Я использую ObjectQuery, но вы можете поменять это с ExecuteStoreQuery - так как они оба возвращают IEnumerable

string myQuery = @"SELECT p.Name,p.VatNumber FROM MyEntities.Users as p";

ProductList.ItemsSource = new ObjectQuery<DbDataRecord>(myQuery, context);

в XAML

<DataGrid AutoGenerateColumns="True" x:Name="ProductList"/>

, и вы увидите возвращаемые столбцыпрямо в интерфейсе.

Если вы не используете WPF и вам нужен Список ваших элементов, то все, что вам нужно сделать, это:

var myList =  new ObjectQuery<DbDataRecord>(myQuery, context).ToList();

или использовать ваш оригинальный методэто будет:

var myList = context.ExecuteStoreQuery<DbDataRecord>("exec spGetProductsByGroup @ProductID={0}", product_id);

Если вам нужно перебирать поля;тогда следующее поможет:

foreach (var rec in context.ExecuteStoreQuery<DbDataRecord>("exec spGetProductsByGroup @ProductID={0}", product_id))
    {
    for (var ri = 0; ri < rec.FieldCount;ri++)
    {
        Console.WriteLine(rec.GetDataTypeName(ri)
                          +"   " + rec.GetName(ri)
                          +" = " + rec.GetValue(ri));
        }
    }

Одна из многих прелестей LINQ и Generics заключается в том, что большую часть времени вы можете просто не слишком беспокоиться о фактических типах данных, пока в конце концов не доберетесь до того места, где вы находитесь.нужно их обработать.

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