1

{"The cast to value type 'System.Int32' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type."}

I am trying to handle null values in a Queryable List with Generic Type T. I have tried DefaultIfEmpty(0) does not work because cannot convert Type T to int. How do I handle nulls or ints To a list?

public  IEnumerable<T> SelectAll<T>(Object TableName)where T:class
{
    String TableNameString = Type.GetType(TableName.ToString()).Name;
            QueryString = "SELECT" + " " + "*" + " " + "FROM" + " " + TableNameString;
    if (Database.Connection.State == ConnectionState.Closed)
        Database.Connection.Open();

    var a = ((IObjectContextAdapter)this).ObjectContext;
    var t = a.ExecuteStoreQuery<T>(QueryString).AsQueryable().DefaultIfEmpty().ToList();
    List<T> newList = t;
    return newList;
}
11
  • How are you calling this method? What is the value of T in your specific case? is it int? Commented Jul 1, 2016 at 14:00
  • Is the column in the database nullable? Commented Jul 1, 2016 at 14:01
  • There are some null columns in the database @YacoubMassad Commented Jul 1, 2016 at 14:03
  • I am calling this method within a class which converts the Type of the Class to T and returns a Listof<classtype> @YacoubMassad Commented Jul 1, 2016 at 14:05
  • If the database table allows nulls in the table, you need to handle that appropriately in the code. You could do this using some SQL in your QueryString. SELECT (prop1, prop2, prop3, ISNULL(prop4, 0), ISNULL(prop5, 'NULL') FROM table_name; where prop4 is an integer type and prop5 is a varchar type. Also, you could put the current query in a single string, QueryString = "SELECT * FROM " + TableNameString; Commented Jul 1, 2016 at 14:06

1 Answer 1

1

(It) does not work because cannot convert Type T to int

It sounds like you need to pass in the type int? but the compiler will not allow it because of the generic parameter constraint. Can you remove this constraint from your method?

where T : class

I don't believe DefaultIfEmpty(0) does what you think it does. For one, it won't take effect until after the failed mapping to type T. Secondly, it doesn't replace null elements with 0. It replaces an empty result set with a result set with exactly one item valued 0.

Here is an example of nullable mappings and how DefaultIfEmpty works.

private void MappingExample()
{
    var complex = GetQuery<ComplexObject>("select Id, null as OptionalAlias from customer").ToArray();
    var simple = GetQuery<int?>("select null as OptionalAlias from customer").ToArray();
}

private void DefaultIfEmptyExample()
{
    var nulls = new int?[] { null, null };
    var nullsWithDefault = simple.DefaultIfEmpty(0); //still full of nulls

    var empty = new int?[] { };
    var emptyWithDefault = empty.DefaultIfEmpty(0); //has one item valued 0
}

private class ComplexObject
{
    public int Id { get; set; }
    public int? OptionalAlias { get; set; }
}

private IEnumerable<T> GetQuery<T>(string sql)
{
    var context = ContextManager.GetNew(); //proprietary, replace with your own
    var parms = new System.Data.SqlClient.SqlParameter[] { };
    return context.Database.SqlQuery<T>(sql, parms);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.