返回自定义对象<列表t>来自实体框架并分配给对象数据源

发布于 2024-12-12 06:02:36 字数 1683 浏览 4 评论 0原文

我需要一些有关问题的指导,我正在使用 Entity Framework 4.0,我有 DAL 和 BLL,并且绑定到页面上的 ObjectDataSource。

我必须使用 PIVOT 和动态 SQL 编写一个存储过程,以按照我想要的方式从多个实体返回数据。现在我试图弄清楚如何让实体框架返回一个自定义对象,我可以将其绑定到页面上的 ObjectDataSource ,我需要使用自定义对象或动态对象,因为存储过程可以返回任意数量的列,因此我无法使用强类型类或实体,并且我还需要能够将其与 ObjectDataSource 绑定。

有人可以指出一个好方法来做到这一点以及如何定义我的函数吗?请提供一些代码示例。

我读到我应该尝试使用 List 返回对象,因为 EF 不支持返回数据表/数据集,到目前为止我有以下内容,但我知道这是不正确的。

我很少使用泛型,如果你能指出如何做到这一点,我相信这会对很多人有帮助。请提供该函数的代码示例以及如何将ObjectDataSource绑定到返回对象?

非常感谢您的帮助!

中使用 DbDataRecord 的建议,我的函数现在看起来是这样的

感谢您的帮助,理查德,根据您关于在 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 C# 函数用于 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 期望定义类或实体吗?如何根据存储过程结果创建一个对象并将其分配给它?

I need some guidance with an issue, I am using Entity Framework 4.0, I have a DAL and BLL and am binding to ObjectDataSource on the page.

I had to write a stored procedure using PIVOT and dynamic SQL to return the data from multiple entities the way I want. Now I am trying to figure out how can I get Entity Framework to return a custom object that I can bind to my ObjectDataSource on the page, I NEED to use a custom object or a dynamic object since the stored procedure can return any number of columns so I can't use a strongly typed class or entity and I need to be also able to bind this with an ObjectDataSource.

Can someone point out a good way to do this and how to define my function? With some code examples please.

I read that I should try to use List<T> for returning an object since EF does not support returning datatables/datasets, I have the following so far but I know this isn't correct.

I have not worked with generics much, if you could point out how to do this I'm sure this would be helpful for a lot of people. Please provide code examples for the function and how to bind ObjectDataSource to the return object?

Your help is greatly appreciated!!

Thanks for your help Richard this is what my function looks like right now based on your suggestion for using DbDataRecord

C# function for ObjectDataSource in 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 in ASPX page

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

Right now I'm getting this error when I access the page:

The result type 'System.Data.Common.DbDataRecord' may not be abstract and must include a default constructor

Is this because the ExecuteStoreQuery expects to be defined class or entity? How can I just create an object based on the stored procedure results and assign it that?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

止于盛夏 2024-12-19 06:02:36

如果您已经有一个与您的 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;
}

If you already have an Entity type that matches your proc return type, use it as the type parameter.

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

Otherwise you could use an ADO.NET DataReader to build the list manually.

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;
}
傲鸠 2024-12-19 06:02:36

像这样的事情怎么样:

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

what about something like this:

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]);
    }
}
寻找我们的幸福 2024-12-19 06:02:36

如果您想在 GridView 中显示结果,那么实际上您已经差不多完成了 - 使用绑定和自动生成列,因为 ObjectQuery 是一个 IEnumerable。 返回 IEnumerable

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

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

我正在使用 ObjectQuery,但您可以将其与 ExecuteStoreQuery 互换 - 因为它们都在 XAML 中

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

,并且您将看到直接在 UI 中返回的列。

如果您没有使用 WPF 并且想要一个元素的 List,那么您需要做的就是:

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 和泛型的众多优点之一是,大多数时候您可以不必过多担心实际的数据类型,直到您最终到达需要处理它们的地方。

If you want to present the results in say a GridView then actually you're nearly there - with the binding and AutoGenerate columns, because ObjectQuery is an IEnumerable. I'm using ObjectQuery but you can interchange this with ExecuteStoreQuery - as they both return an IEnumerable

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

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

in the XAML

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

and you'll see the columns that are returned directly in the UI.

If you're not using WPF and you want a List of your elements then all you need to do is:

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

or to take your original method it would be:

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

If you do need to iterate over the fields; then the following will do the trick:

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

One of the many beauties of LINQ and Generics is that most of the time you can simply not worry too much about the actual datatypes until you eventually get to where you need to process them.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文