【问题标题】:DataBinder.Eval returns null, although the field is populatedDataBinder.Eval 返回 null,尽管该字段已填充
【发布时间】:2015-09-01 07:12:18
【问题描述】:

我在 asp.net 应用程序中显示我的一个实体的对象字段时遇到问题。 DataBinder.Eval 出于某种原因返回 Nothing

我有 2 个类如下:

Public Class Bench
    <ScaffoldColumn(False), StringLength(50), Key> _
    Public Property Code() As String

    <Required> _
    Public Property Type() As BenchType

    <Required, StringLength(50)> _
    Public Property Name() As String

    ...
End Class

Public Class BenchType
    <ScaffoldColumn(False), Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)> _
    Public Property ID() As Integer

    <Required, StringLength(50)> _
    Public Property Name() As String

    ...
End Class

我正在尝试在GridView 中显示Bench 实体,如下所示(使用正确实现的ObjectDataSource odsBenches):

<asp:GridView ID="grwBenches" runat="server" DataSourceID="odsBenches"
    DataKeyNames="Code,Type,Name" AutoGenerateColumns="false">
    <Columns>
        <asp:TemplateField HeaderText="Code">
            <ItemTemplate>
                <asp:Label id="lblCode" runat="server" Text='<%# Bind("Code")%>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Name">
            <ItemTemplate>
                <asp:Label id="lblName" runat="server" Text='<%# Bind("Name")%>'></asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Bench Type">
            <ItemTemplate>
                <asp:Label id="lblBenchType" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Type.Name")%>'>
                </asp:Label>
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
</asp:GridView>

CodeName 字段显示正常,但 Type 字段显示为空,这是渲染页面的结果标记:

<table cellspacing="0" rules="all" border="1" id="MainContent_grwBenches" style="border-collapse:collapse;">
    <tr>
        <th scope="col">Code</th><th scope="col">Name</th><th scope="col">Bench Type</th>
    </tr><tr>
        <td>
                <span id="MainContent_grwBenches_lblCode_0">OK Code</span>
            </td><td>
                <span id="MainContent_grwBenches_lblName_0">OK Name</span>
            </td><td>
                <span id="MainContent_grwBenches_lblBenchType_0"></span>
            </td>
    </tr>
</table>

当我单步执行代码时,&lt;%# DataBinder.Eval(Container.DataItem, "Type.Name")%&gt; 似乎返回 Nothing,但是当我检查数据库时,Type 字段包含类型代码。

可能是什么问题?

编辑(DAL 代码):

Public Function GetBenches() As IQueryable(Of Bench)
    Return _db.BENCHES
End Function

_db 是 DBContext 对象。

【问题讨论】:

  • 您可以尝试 如果这是 Nothing(它应该是 .ToString() 的结果),那么您的代码会返回一个null 类型实例。数据库没问题不代表代码没问题。
  • 确实是这样,但我使用实体框架自动从对象生成数据库。我应该检查什么?
  • 这样的话,你的意思是&lt;%# DataBinder.Eval("Type") %&gt;什么都不是?在这种情况下,您可以在一个小型控制台应用程序中检查发生了什么。只需使用 ObjectDataSource 使用的方法并调试它给出的结果。或者,如果您使用 SQL Server,请查看 SQL Server profiler。
  • 在命令窗口中,? Eval("Type") 返回 Nothing。我查询数据库,有一个名为 Type_ID 的字段,它填充了正确的 ID。我试过Eval("Type_ID")但这导致了一个错误。
  • 如果 Type 什么都不返回,那么是的,它肯定解释了为什么 Type.Name 也是 null。 DataBinder.Eval 只是在空中间对象上静默失败(如本例中的 Type)

标签: asp.net vb.net entity-framework data-binding


【解决方案1】:

不应该吗?

  <asp:Label id="lblBenchType" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "BenchType.Name")%>'>

因为

  Public Property Type() As BenchType

【讨论】:

  • 感谢建议,试过了,还是不行。 BenchType是类名,应该是属性名。
  • 您是否检查过 BenchType 是否返回有效的 ID 和名称?
  • Type 字段返回 Nothing,因此无法访问 IDName 字段
【解决方案2】:

这对我有用。

<asp:TemplateField HeaderText="Bench Type">
        <ItemTemplate>
            <asp:Label id="lblBenchType" runat="server" Text='<%# Bind("Type.Name")%>'></asp:Label>
        </ItemTemplate>
    </asp:TemplateField>

【讨论】:

    【解决方案3】:

    只是一个盲目的尝试,但你应该有一个 New 构造函数吗?

    Public Class Bench
        Public Sub new()
           Me.Type=new BenchType
        End Sub
    
    
    <ScaffoldColumn(False), StringLength(50), Key> _
    Public Property Code() As String
    
    <Required> _
    Public Property Type() As BenchType
    
    <Required, StringLength(50)> _
    Public Property Name() As String
    
    ...
    End Class
    

    我想知道数据库是否因为尚未实例化类而无法填充。

    【讨论】:

    • EF 应该自己填充字段,NameCode 字段可以毫不费力地填充,但是 Type 字段有些东西。
    • 正确,你试过了吗?该类型不是本机字段,而是一个类。除非它被显式分配,否则它可能会导致对象实例化错误。您可以只调暗一个字符串并能够设置它的值;内存是动态分配的。对于一个班级来说并非如此。您可以尝试将类更改为结构吗?
    【解决方案4】:

    Eval 正在寻找对象名称和属性名称,在这种情况下,对象是“类型”,属性是“名称”。所以长话短说,这应该有效。我认为问题在于“类型”是保留关键字。尝试将子类的名称更改为更具描述性的名称,看看是否会有所不同。我希望这会有所帮助。

    <asp:TemplateField>
        <ItemTemplate>
            <asp:Label Id="lblSubclassVal" runat="server" Text="<%# DataBinder.Eval(Container.DataItem, "SubClass.PropertyName")%>"></asp:Label>
        </ItemTemplate>
    </asp:TemplateField>
    

    【讨论】:

    • 我尝试将Type 更改为其他内容,但没有成功。
    【解决方案5】:

    作为

    [type]是用户定义的类型

    Public Property Type() As BenchType
    

    Public Class BenchType
        <ScaffoldColumn(False), Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)> _
        Public Property ID() As Integer
    
        <Required, StringLength(50)> _
        Public Property Name() As String
    
        ...
    End Class
    

    所以,你通常不能像这样在网格视图中绑定这种类型

     <asp:Label id="lblBenchType" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Type.Name")%>'>
    

    或类似的东西

    <asp:Label id="lblBenchType" runat="server" Text='<%# Eval("Type.Name")%>'>
    

    解决方案:

    首先,你需要将结果数据转换为类型,然后 通过其属性名称获取所需的值。

     <asp:Label ID="lb1" runat="server" Text='<%# (Eval("Type") as BenchType).Name %>'></asp:Label>
    

    N:B 我不熟悉 Vb.Net,我用 C# 编写了代码

    【讨论】:

    • 我可以使用 Text='&lt;%# Eval("Type.Name")%&gt;' 进行预加载并允许序列化。
    • 感谢您的建议。如果未实现预加载和序列化,这将不起作用。
    【解决方案6】:

    问题似乎是由于以下原因:

    • BenchType 对象不可序列化
    • SELECT 方法使用延迟加载而不是急切加载

    必须进行以下更改;

    如下更改BenchType类:

    <Serializable> _
    Public Class BenchType
        <ScaffoldColumn(False), Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)> _
        Public Property ID() As Integer
    
        <Required, StringLength(50)> _
        Public Property Name() As String
    
        ...
    End Class
    

    如下更改 DAL SELECT 方法:

    Public Function GetBenches() As IQueryable(Of Bench)
        Return (From c In _db.BENCHES.Include("Type") Select c)
    End Function
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-15
      • 2019-05-09
      • 2020-07-25
      • 2014-11-02
      • 2020-11-24
      • 1970-01-01
      • 2013-10-31
      相关资源
      最近更新 更多