web-dev-qa-db-fra.com

DataSet ne prend pas en charge System.Nullable <> dans Export

J'essayais de générer un rapport en utilisant Exporter vers Excell, PDF, TextFile. Eh bien, je fais ça dans MVC. J'ai une classe que j'ai nommée SPBatch (qui est le nom exact de ma procédure stockée dans mon SQL) et qui contient les éléments suivants:

public string BatchNo { get; set; }
public string ProviderName { get; set; }
public Nullable<System.Int32> NoOfClaims { get; set; }
public Nullable<System.Int32> TotalNoOfClaims { get; set; }
public Nullable<System.Decimal> TotalBilled { get; set; }
public Nullable<System.Decimal> TotalInputtedBill { get; set; }
public Nullable<System.DateTime> DateCreated { get; set; }
public Nullable<System.DateTime> DateSubmitted { get; set; }
public Nullable<System.DateTime> DueDate { get; set; }
public string Status { get; set; }
public string RefNo { get; set; }
public string BatchStatus { get; set; }
public string ClaimType { get; set; }

comme vous pouvez le voir, certaines de mes colonnes sont déclarées nulles. La recherche et l'affichage des résultats dans un tableau se sont bien déroulés. J'ai plusieurs boutons ci-dessous qui sont des boutons d'image pour l'exportation et chaque fois que j'essaie d'exporter dans Excel, j'ai toujours le problème "DataSet ne prend pas en charge System.Nullable <>" dans cette partie de mon code :

foreach (MemberInfo mi in miArray)
{
    if (mi.MemberType == MemberTypes.Property)
    {
        PropertyInfo pi = mi as PropertyInfo;
        dt.Columns.Add(pi.Name, pi.PropertyType); //where the error pop's up.

    }
    else if (mi.MemberType == MemberTypes.Field)
    {
        FieldInfo fi = mi as FieldInfo;
        dt.Columns.Add(fi.Name, fi.FieldType);
    }
}

l'erreur apparaît sur celui avec un commentaire. Pouvez-vous m'aider quoi faire? J'ai essayé d'ajouter DBNull dans mon code mais j'obtiens toujours la même erreur. J'ai essayé de supprimer Nullable dans mon SPBatch mais j'obtiens une erreur indiquant que certaines tables doivent être déclarées Nullable.

Que devrais-je faire?

43
Ms. B

essayer avec

dt.Columns.Add(pi.Name, Nullable.GetUnderlyingType(
            pi.PropertyType) ?? pi.PropertyType);
108
Damith

Grâce à une version C # d'une génération de table de données et à du piratage, je peux offrir cette réponse dans VB - Je la mets ici parce que j'ai juste eu beaucoup de tracas à vouloir obtenir un ensemble de données filtrable à partir d'un proc stocké tout en utilisant une simple base de données. J'espère que cela aide quelqu'un d'autre!

Remarque: Le cas d'utilisation est celui où vous souhaitez utiliser BindingSource.Filter = "une chaîne de requête":

Imports System.Reflection

Public Module Extenders
<System.Runtime.CompilerServices.Extension>
Public Function ToDataTable(Of T)(collection As IEnumerable(Of T), tableName As String) As DataTable
    Dim tbl As DataTable = ToDataTable(collection)
    tbl.TableName = tableName
    Return tbl
End Function

<System.Runtime.CompilerServices.Extension>
Public Function ToDataTable(Of T)(collection As IEnumerable(Of T)) As DataTable
    Dim dt As New DataTable()

    Dim tt As Type = GetType(T)
    Dim pia As PropertyInfo() = tt.GetProperties()

    'Create the columns in the DataTable

    For Each pi As PropertyInfo In pia
        Dim a = 
If(Nullable.GetUnderlyingType(pi.PropertyType), pi.PropertyType)
        dt.Columns.Add(pi.Name, If(Nullable.GetUnderlyingType(pi.PropertyType), pi.PropertyType))
    Next

    'Populate the table

    For Each item As T In collection
        Dim dr As DataRow = dt.NewRow()
        dr.BeginEdit()

        For Each pi As PropertyInfo In pia

            dr(pi.Name) = If(Nullable.GetUnderlyingType(pi.PropertyType) Is GetType(DateTime), DBNull.Value, pi.GetValue(item, Nothing))
        Next
        dr.EndEdit()
        dt.Rows.Add(dr)
    Next
    Return dt
End Function

End Module
4
Richard Griffiths

Je rechercherais nullable et le remplacerais par une chaîne qui peut être nulle contrairement à un DateTime.

foreach (PropertyInfo pi in properties)
{
    if (pi.PropertyType.Name.Contains("Nullable"))
       myDataType = typeof(String);
    else
       myDataType = pi.PropertyType;
}

Voici une version complète:

private DataTable CreateDataTable(PropertyInfo[] properties)
{
    DataTable dt = new DataTable();
    DataColumn dc = null;
    foreach (PropertyInfo pi in properties)
    {
        dc = new DataColumn();
        dc.ColumnName = pi.Name;

        if (pi.PropertyType.Name.Contains("Nullable"))
            dc.DataType = typeof(String);
        else
            dc.DataType = pi.PropertyType;

        // dc.DataType = pi.PropertyType;
        dt.Columns.Add(dc);
    }
    return dt;
}
1
Ross Bush