LLBLGen default variable field values reads not null but are null - llblgenpro

I have an LLBLGen entity.
MyEntity{
public Decimal Foo; //Stored in database as a NOT NULL field
}
....
public void SomeMethod(){
MyEntity entity = new MyEntity(); //on initial inspection Foo reads as "0"
adapter.SaveEntity(entity); //will throw exception, "Foo can't be assigned a NULL value"
//but on debug inspection, Foo = 0
entity.Foo = 14M;
adapter.SaveEntity(entity); //will save ok.
}
If I don't assign a value to a number, the debugger reads it as not null, however, it throws an exception telling me that it's actually NULL.
I was trusting LLBLgen to auto assign all variables a default value, but I can't be so sure now.
Anyone able to shed some light on this please. Thanks.

The LLBLGen Pro runtime doesn't assign default values automatically, however you can specify it as default constraints in your database.
You can check if a field has a value assigned by checking the 'Fields' collection on your entity:
bool isValueAssigned = myEntity.Fields[(int)MyFieldIndex.Foo].CurrentValue!=null;

Related

Handle NullObjects across two models web api

I have two models in my asp.net web api. One is the database model, and the other is the model the end user passes in and we map the properties like this:
public static IndividualProc ToIndividualnternal(this AssignmentExternal item) {
return new IndividualProc() {
IndividualID = (int)item.person.id,
EventID = (int)item.event.id,
EventScehduleID = item.schedule.id,
EventGroupID = item.group.id
};
}
The problem is that when the user passes a null, I get an exception; "Nullable object must have a value". How can I cast the nullable properties so that this exception is not caused?
What's nullable? For the purpose of this answer I'm going to assume this is a nullable int:
item.event.id
and this is a regular int:
EventID
In that case, clearly you can't directly cast the former to the latter because there's no way for int to handle the case of a null value. The Nullable<t> structure has properties to help check for that value:
EventID = item.event.id.HasValue ? item.event.id.Value : default(int)
This will check if the nullable int has a value and, if it does, use that value. If it doesn't, use the default value for int (which is 0).

Web API validation error

I have a View Model called SignUp with the EmailAddress property set like this:
[Required]
[DuplicateEmailAddressAttribute(ErrorMessage = "This email address already exists")]
public string EmailAddress { get; set; }
and the custom validator looks like this:
public class DuplicateEmailAddressAttribute : ValidationAttribute
{
public override bool IsValid(object value)
{
PestControlContext _db = new PestControlContext();
int hash = value.ToString().GetHashCode();
if (value == null)
{
return true;
}
if (_db.Users.Where(x => x.EmailAddressHash == hash).Count() > 0)
return false;
else
return true;
}
}
The problem I'm having is that if the user leaves the email address field blank on the sign up form the application is throwing a null reference exception error (I think it's looking for "" in the database and can't find it). What I don't understand is why this isn't being handled by the Required attribute - why is it jumping straight into the custom validator?
The Required attribute would have resulted in an error being added to the model state. It will not short-circuit the execution though. The framework continues to run other validators for the simple reason that all the errors about the request need to be sent out in a single shot. Ideally, you wouldn't want the service to say something is wrong to start with and when the user re-submits the request after making a correction, the service comes back and say some other thing is wrong and so on. It will be an annoyance, I guess.
The NullReferenceException is thrown because value.ToString() is called before the check against null. As you need the hash variable only after the check, you can solve this by reordering the statements:
if (value == null)
{
return true;
}
int hash = value.ToString().GetHashCode();
In addition, you could also move the PestControlContext after the check against null and use a using statement to dispose of it properly.
As also #Baldri pointed out, each validator can add Error messages and all of them are run, even if a previous one already signaled the data to be invalid. Furthermore, I'd not rely on that the validations are run in the order that you specify when marking the property with the attributes (some frameworks implement their own attribute ordering mechanism in order to assert that the order is deterministic, e.g. priorities or preceding attributes).
Therefore, I suggest reordering the code in the custom validator is the best solution.

Cannot map raw SQL query to DataRow

I am trying to get IEnumerable from linq query below. What am I doing wrong?
IEnumerable<DataRow> results =
context.Database.SqlQuery<DataRow>("SELECT * FROM Customer").AsEnumerable();
DataRow class does not have default (parameterless) constructor, so you can't use it as query parameter type. There is no generic constraints on type parameter, and nothing mentioned on MSDN(!), but column map factory will throw exception if parameter type does not have default constructor:
The result type 'System.Data.DataRow' may not be abstract and must
include a default constructor.
Here is a code which throws this exception:
internal static CollectionColumnMap CreateColumnMapFromReaderAndClrType(
DbDataReader reader, Type type, MetadataWorkspace workspace)
{
BindingFlags flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
ConstructorInfo constructor = type.GetConstructor(flags, (Binder) null, Type.EmptyTypes, (ParameterModifier[]) null);
if (type.IsAbstract || (ConstructorInfo) null == constructor && !type.IsValueType)
throw EntityUtil.InvalidOperation(InvalidTypeForStoreQuery((object) type));
// ...
}
BTW Mapping to DataRow makes no sense, even if it would have default public constructor. Because it is not simple primitive type and it does not have properties which match the names of columns returned from the query (yes, mapping uses properties only).
Correct usage of Linq will be
IEnumerable<Customer> results = context.Customers;
That will generate SELECT * FROM Customer query, and map query results to customer entities. If you really want to use raw SQL:
IEnumerable<Customer> results =
context.Database.SqlQuery<Customer>("SELECT * FROM Customers");
I think we were trying to solve the same problem (Google led me here, anyway). I am executing a raw SQL command through SqlQuery<TElement>(string sql, params object[] parameters and wanted to assert individual properties of the results returned from the query in a unit test.
I called the method:
var result = (db.SqlQuery<Customer>("select * from customers").First();
and verified the data it returned:
Assert.AreEqual("John", result.FirstName);
I defined a private class Customer inside my test class (unfortunately, I'm not using Entity Framework):
private class Customer
{
public string FirstName { get; set; }
}
The properties of Customer must match the column names returned in the SQL query, and they must be properties (not just variables of the Customer class. You don't have to create properties for all of the columns returned from the query.

Updating an item using LINQ, not working

Good day!
I have this query as shown below:
jt.SummarySpecs.Where(
x => true
)
.FirstOrDefault()
.DocSpecs
.Where(
x => x.DocID == x.DocID
)
.FirstOrDefault()
.FinishingOptionsDesc[0] = option;
But when the code get executed, value for finishingOptionsDesc[0] is not updating...
what's wrong with the query above?
The classes attributes:
"SummarySpecs.cs"
public DocSpec[] DocSpecs { get; set; }
"DocSpecs.cs"
public string[] FinishingOptionsDesc { get; set; }
My only concern is to update the FinishingOptionDesc 1st string.
Thanks
That error means something is null. You have 4 unchecked places in one statement where there could be a null return value. Either of the calls to FirstOrDefault could return null if those collections were empty. Or DocSpecs could be null on the returned object, or FinishingOptionsDesc could be null.
Ideally you'd break this statement up a bit and insert null checks. You could say that you know none of these points should ever be null. If that is the case it may be valid to allow an exception to occur, but arguably it is still worth breaking up the statement to get better error reporting on where the exception occurred.
Try something like this..
UPDATE
if(jt.SummarySpecs.Select(a=>a.DocSpecs).Any())
{
var docSpecs = jt.SummarySpecs.Select(a => a.DocSpecs)
docSpecs.FinishingOptionsDesc[0] = option;
}

Linq throwing exception when Null is returned to a string - attribute on a class?

I have a Linq query which I am selecting into a string, of course a string can contain null!
So is there a way I can throw an exception within my Linq query, if I detect a null?
Can I decorate my class with an attribute that won't let it allow null?
I would like to wrap my Linq query in a try catch, and as soon as a null is detected then it would enter the catch, and I can handle it.
Edit
Here's my Linq query, it's quite simple currently. I am going to extend it, but this shows the basic shape:
var localText = from t in items select new Items { item = t.name }
Basically item is set to t.name, t.name is a string so it could be empty / null is this perfectly legal as its a string and strings can hold NULL.
So if it returns NULL then I need to throw an exception. Actually it would be handy to be able to throw an exception is NULL or empty.
I seemed to remember some kind of Attributes that can be set on top of properties that says "Don't accept null" etc.?
Edit
I think I found it: http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.requiredattribute.aspx
This doesn't allow null or strings so I presume it throws an exception, I have used this with MVC but I am not sure if I can use it with a standard class.
As a string being null isn't particularly exceptional, you could do something like:
var items = myStrings.Where(s => !string.IsNullOrEmpty(s)).Select(s => new Item(s));
UPDATE
If you are reading this data from an XML file, then you should look into LINQ to XML, and also use XSD to validate the XML file rather than throwing exceptions on elements or attributes that don't contain strings.
You could try intentionally generating a NullReferenceException:
try
{
//Doesn't change the output, but throws if that string is null.
myStrings.Select(s=>s.ToString());
}
catch(NullReferenceException ex)
{
...
}
You could also create an extension method you could tack on to a String that would throw if null:
public static void ThrowIfNull(this string s, Exception ex)
{
if(s == null) throw ex;
}
...
myString.ThrowIfNull(new NullReferenceException());
Why do you want to throw an exception in this case? This sounds like throwing the baby out with the bath water for something that should not happen in the first place.
If you just want to detect that there are null/empty items:
int nullCount= items.Count( x=> string.IsNullOrEmpty(x.name));
If you want to filter them out:
var localText = from t in items where !string.IsNullOrEmpty(t.name) select new Items { item = t.name };

Resources