【问题标题】:"Current" object of an asp:FormView bound to an EntityDataSourceasp 的“当前”对象:FormView 绑定到 EntityDataSource
【发布时间】:2010-03-04 20:05:44
【问题描述】:

我有一个启用分页的 FormView。 FormView 绑定到 EntityDataSource ...

<asp:EntityDataSource ID="MyEntityDataSource" runat="server" 
    ConnectionString="name=MyEntitiesContext" 
    DefaultContainerName="MyEntitiesContext" 
    EntitySetName="Order" 

    // ... more stuff to define a query

</asp:EntityDataSource>

... 从数据库中返回 Order 类型的对象列表 (IEnumerable)。假设我的寻呼机位于第 2 页,因此 FormView 显示列表的第二个对象。

FormView 似乎“知道”它必须显示的对象,因为像这样的控件

<asp:Label ID="MyLabel" runat="server" Text='<%# Eval("MyProperty")%>'/>

神奇地显示正确对象的“MyProperty”值。

如何在代码隐藏中访问这个对象(Order 类型的实体作为一个整体,而不是使用“Eval”的单个属性)?

【问题讨论】:

    标签: asp.net entity-framework formview entitydatasource


    【解决方案1】:

    在 FormView 的 DataBound 事件处理程序中,您可以执行以下操作:

    Advert ad = FormView1.DataItem.WrappedEntity<Advert>();
    

    .WrappedEntity() 是一个扩展方法,定义为:

    /// <summary>
    /// Gets the actual EF entity object that is being wrapped and databound.
    /// </summary>
    /// <example>
    /// Advert ad = myFormView.DataItem.WrappedEntity<Advert>();
    /// (where myFormView is databound to EntityDataSource returning Advert entity)
    /// </example>
    static class WrappedEFEntityExtensions
    {
        public static TEntity WrappedEntity<TEntity>(this object dataItem) where TEntity : class
        {
            var entity = dataItem as TEntity;
    
            if (entity != null)
                return entity;
    
            var typeDescriptor = dataItem as ICustomTypeDescriptor;
    
            if (typeDescriptor != null)
                return (TEntity)typeDescriptor.GetPropertyOwner(null);
    
            return null;
        }
    }
    

    这些示例使用 EF 实体 Advert,但您可以替换为例如 Order。

    http://www.dontcodetired.com/blog/post/Accessing-Entity-Framework-Entity-In-EntityDataSource-Data-Bound-Controls.aspx

    完整的示例标记和代码:

    <%@ Page Language="C#" AutoEventWireup="true" CodeFile="stackOF.aspx.cs" Inherits="stackOF" %>
    <%@ Register Assembly="System.Web.Entity, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
        Namespace="System.Web.UI.WebControls" TagPrefix="asp" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>    
            <asp:EntityDataSource ID="EntityDataSource1" runat="server" 
                ConnectionString="name=mototradeEntities" 
                DefaultContainerName="mototradeEntities" EntitySetName="Adverts">
            </asp:EntityDataSource>
    
    
            <asp:FormView ID="FormView1" runat="server" AllowPaging="True" 
                DataKeyNames="ID" DataSourceID="EntityDataSource1" 
                ondatabound="FormView1_DataBound">                        
                <ItemTemplate>
                    ID:<asp:Label ID="IDLabel" runat="server" Text='<%# Eval("ID") %>' />
                    <%-- other properties here --%>
                </ItemTemplate>
            </asp:FormView>    
        </div>
            <asp:Label ID="lblTest" runat="server" Text="Label"></asp:Label>
        </form>
    </body>
    </html>
    

    后面的代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.ComponentModel;
    using mototradeModel;
    
    public partial class stackOF : System.Web.UI.Page
    {
         protected void FormView1_DataBound(object sender, EventArgs e)
        {
            Advert ad = FormView1.DataItem.WrappedEntity<Advert>();
            if (ad != null)
            {
                lblTest.Text = "current object databound to FormView1: " + ad.ID;
            }
        }
    }
    
    /// <summary>
    /// Gets the actual EF entity object that is being wrapped and databound.
    /// </summary>
    /// <example>
    /// Advert ad = myFormView.DataItem.WrappedEntity<Advert>();
    /// (where myFormView is databound to EntityDataSource returning Advert entity)
    /// </example>
    static class WrappedEFEntityExtensions
    {
        public static TEntity WrappedEntity<TEntity>(this object dataItem) where TEntity : class
        {
            var entity = dataItem as TEntity;
    
            if (entity != null)
                return entity;
    
            var typeDescriptor = dataItem as ICustomTypeDescriptor;
    
            if (typeDescriptor != null)
                return (TEntity)typeDescriptor.GetPropertyOwner(null);
    
            return null;
        }
    }
    

    【讨论】:

    • 哇,太好了!我已经对其进行了测试,并且可以正常工作!看来我问的时间对了,你的文章才几天前 :) 我会更详细地研究,也会阅读 Diego Vega 的链接文章。但是,我真的很想知道为什么我觉得非常基本的东西(最终访问控件正在使用的对象)隐藏在幕后,需要“扩展”和对实体框架的深入理解。好吧,很明显,我真的必须努力解决我对框架缺乏洞察力的问题,因为我自己从来没有找到像这样的解决方案。
    • 很高兴能帮上忙 :) 我认为包装器与为外键/相关表或其他东西提供支持有关。
    猜你喜欢
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    相关资源
    最近更新 更多