none
Getting non-nullable property in EntityFramework Entity to accept empty string RRS feed

  • Question

  • Hello,

    I have a situation in which I'm dealing with EntityFramework and a field in an Entity that is set to not allow nulls. I have an ICsvReader that's reading values from a CSV file, and these values are being used to initialize the Entity. When it encounters a blank value for the field BowtieCenter in the CSV, it converts that to null when assigning it to the non-nullable property BowtieCenter in the Entity. The result is that the Entity the reader returns is null.

    This was fine in all case, but now we want to implement something that requires us to set that property to a non-null value, like an empty string instead. The reason we want to do this is that, under certain condtions, we want to give the user a warning that the CSV field is blank and should be set to something. The conditions are: 1) that a second field (called BowtieEquipment) is set to something, or 2) that a third (called DataMiningEquipment) is set to something. If either or both of these conditions are met, the user needs to fill in BowtieCenter with something.

    The problem is that when BowtieCenter is blank, the reader returns null for my Entity, which means I can't even check if the properties BowtieEquipment or DataMiningEquipment are set to something.

    I tried a couple things, neither of which worked:

    1) I tried setting the default value for the BowtieCenter property to String.Empty:

        public class BowtieMap : CsvClassMap<Bowtie>
        {
            public BowtieMap()
            {
    ...
    Map(b => b.Center).Index(6).Default(string.Empty);
    ...
    }
        }

    But the Entity (Bowtie) still comes back null.

    2) I tried creating a special function that parses the value:

        public class BowtieMap : CsvClassMap<Bowtie>
        {
            public BowtieMap()
            {
    ...
    Map(b => b.Center).ConvertUsing(x => x.ParseBowtieCenter(6));
    ...
    }
        }

    ...

            public static string ParseBowtieCenter(this ICsvReaderRow x, int fieldIndex)
            {
                return x.GetField(fieldIndex).Trim();
            }

    But still I get null.

    I even tried sending back a non-empty string but still whitespace:

            public static string ParseBowtieCenter(this ICsvReaderRow x, int fieldIndex)
            {
       var field = x.GetField(fieldIndex).Trim();

                return field == string.Empty ? " " : field;
            }

    But still null.

    Finally, I tried this:

            public static string ParseBowtieCenter(this ICsvReaderRow x, int fieldIndex)
            {
       var field = x.GetField(fieldIndex).Trim();

                return field == string.Empty ? "_" : field;
            }

    This is the only thing that works. Apparently, the value returned for BowtieCenter can't be whitespace at all.

    Why not? Why does EntityFramework insist on treating "        /t/t/t          /n/n   /r/r    " as no different from null?

    Is there a way to GET it to allow whitespace as an acceptable non-null value? Preferably empty string?

    Returning a non-whitespace string just seems like bad programming to me.

    And no, allowing for null in the database or the Entity is not an option (after I check the values of BowtieEquipment and DataMiningEquipment, I will set the Bowtie Entity to null if necessary).

    Thanks for your help.
    Friday, December 23, 2016 12:41 AM

All replies

  • Hello,

    I have a situation in which I'm dealing with EntityFramework and a field in an Entity that is set to not allow nulls. I have an ICsvReader that's reading values from a CSV file, and these values are being used to initialize the Entity. When it encounters a blank value for the field BowtieCenter in the CSV, it converts that to null when assigning it to the non-nullable property BowtieCenter in the Entity. The result is that the Entity the reader returns is null.

    This was fine in all case, but now we want to implement something that requires us to set that property to a non-null value, like an empty string instead. The reason we want to do this is that, under certain condtions, we want to give the user a warning that the CSV field is blank and should be set to something. The conditions are: 1) that a second field (called BowtieEquipment) is set to something, or 2) that a third (called DataMiningEquipment) is set to something. If either or both of these conditions are met, the user needs to fill in BowtieCenter with something.

    The problem is that when BowtieCenter is blank, the reader returns null for my Entity, which means I can't even check if the properties BowtieEquipment or DataMiningEquipment are set to something.

    I tried a couple things, neither of which worked:

    1) I tried setting the default value for the BowtieCenter property to String.Empty:

        public class BowtieMap : CsvClassMap<Bowtie>
        {
            public BowtieMap()
            {
    ...
    Map(b => b.Center).Index(6).Default(string.Empty);
    ...
    }
        }

    But the Entity (Bowtie) still comes back null.

    2) I tried creating a special function that parses the value:

        public class BowtieMap : CsvClassMap<Bowtie>
        {
            public BowtieMap()
            {
    ...
    Map(b => b.Center).ConvertUsing(x => x.ParseBowtieCenter(6));
    ...
    }
        }

    ...

            public static string ParseBowtieCenter(this ICsvReaderRow x, int fieldIndex)
            {
                return x.GetField(fieldIndex).Trim();
            }

    But still I get null.

    I even tried sending back a non-empty string but still whitespace:

            public static string ParseBowtieCenter(this ICsvReaderRow x, int fieldIndex)
            {
       var field = x.GetField(fieldIndex).Trim();

                return field == string.Empty ? " " : field;
            }

    But still null.

    Finally, I tried this:

            public static string ParseBowtieCenter(this ICsvReaderRow x, int fieldIndex)
            {
       var field = x.GetField(fieldIndex).Trim();

                return field == string.Empty ? "_" : field;
            }

    This is the only thing that works. Apparently, the value returned for BowtieCenter can't be whitespace at all.

    Why not? Why does EntityFramework insist on treating "        /t/t/t          /n/n   /r/r    " as no different from null?

    Is there a way to GET it to allow whitespace as an acceptable non-null value? Preferably empty string?

    Returning a non-whitespace string just seems like bad programming to me.

    And no, allowing for null in the database or the Entity is not an option (after I check the values of BowtieEquipment and DataMiningEquipment, I will set the Bowtie Entity to null if necessary).

    Thanks for your help.
    Friday, December 23, 2016 12:40 AM
  • Hi gib898,

    Thank you for posting here.

    According to your question is more related to Entity Framework, I will move it to ADO.NET Entity Framework and LINQ to Entities forum for suitable support.

    The Visual C# discuss and ask the C# programming language, IDE, libraries, samples and tools.

    If you have some grammar or code errors, please feel free to contact us. We will try our best to give you a solution.

    Thanks for your understanding and cooperation.

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, December 23, 2016 7:37 AM
  • Hi gib898,

    1. If variable named field is a object, please try the following code.

     public static string ParseBowtieCenter(this ICsvReaderRow x, int fieldIndex)
             {
       var field = x.GetField(fieldIndex).Trim();
    
                 return field == null? "_" : field.ToString();
             }
    
    2. If variable named field is a string, please try the following code.

    public static string ParseBowtieCenter(this ICsvReaderRow x, int fieldIndex)
     {
       var field = x.GetField(fieldIndex).Trim();
        if (string.IsNullOrEmpty(field))
             return "_";
        else
             retrun field;           
    }

    Best regards,

    Cole Wu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, December 23, 2016 8:24 AM
    Moderator
  • Hi gib898,

    1. If variable named field is a object, please try the following code.

     public static string ParseBowtieCenter(this ICsvReaderRow x, int fieldIndex)
             {
       var field = x.GetField(fieldIndex).Trim();
    
                 return field == null? "_" : field.ToString();
             }
    2. If variable named field is a string, please try the following code.

    public static string ParseBowtieCenter(this ICsvReaderRow x, int fieldIndex)
     {
       var field = x.GetField(fieldIndex).Trim();
        if (string.IsNullOrEmpty(field))
             return "_";
        else
             retrun field;           
    }

    Best regards,

    Cole Wu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    That's the opposite of what I want.

    The variable "field" is already a string. I don't need to convert it. If it's null, I DON'T want to return "_", I want to return string.Empty or some kind of whitespace. I repeat that the problem is that returning empty strings or whitespace doesn't actually give me empty strings or whitespace. I get a null object.

    Again, here's the situation: the reader is reading a blank in the CSV, when it reads blank, it returns null. It tries to assign that null value to Bowtie.Center. Because Bowtie.Center does not allow nulls, the entire bowtie object itself I get back is null. I'm trying to override the default parsing functionality with ParseBowtieCenter() which I'm trying to force to return empty string or whitespace but even that's being converted to null, thus bowtie itself is still null. Setting it to "_" is the only way to avoid this, but I don't want "_".

    Friday, December 23, 2016 3:01 PM
  • Hi gib898,

    You could replace "_" to string.Empty.PadRight(20).  like this:

    public static string ParseBowtieCenter(this ICsvReaderRow x, int fieldIndex)
     {
       var field = x.GetField(fieldIndex).Trim();
        if (string.IsNullOrEmpty(field))
             return string.Empty.PadRight(20);
        else
             retrun field;           
    }

    Best regards,

    Cole Wu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    Monday, December 26, 2016 1:35 AM
    Moderator
  • I must apologize. The problem had nothing to do with the Bowtie entity or the CsvReader.

    Apparently, we had some code in our application that was nullifying the Bowties when the first field is blank. I didn't know it was there and the developer who wrote it no longer works here.

    It was this:

        public partial class Bowtie : IEmpty, IAuditable
        {
            public bool IsEmpty()
            {
                return string.IsNullOrWhiteSpace(Center);
            }
        }

    This method, which is a required override for IEmpty, returns false when Center is null or whitespace (the first field). I guess this was resulting in Bowtie being null. When I change it to:

        public partial class Bowtie : IEmpty, IAuditable
        {
            public bool IsEmpty()
            {
                return string.IsNullOrWhiteSpace(Center)
                    && string.IsNullOrWhiteSpace(BowtieCenterEquipment)
                    && (BowtieDMEquipmentLookupId == null || BowtieDMEquipmentLookupId == 0);
            }
        }

    I get the desired effect.


    Wednesday, December 28, 2016 3:43 PM
  • Hi gib898,

    I am glad to know you solved this problem and thanks for sharing the solution. please mark it as answer. It will be very beneficial for other community members who have the similar questions.


    Best regards,

    Cole Wu


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, December 30, 2016 7:15 AM
    Moderator