Here is a portion of a code ..
public Admin_GetCourseById_spResult GetCourseById(long? courseId, short languageId)
{
ISQUserDataContext db = CreateDataContext();
Admin_GetCourseById_spResult result;
result = db.Admin_GetCourseById_sp(courseId,false,languageId).FirstOrDefault();
return result;
}
the third line in the function throws error Specified cast is not valid.
Any clue about whats happening ??
Small rewrite (needs more work)
public Course GetCourseById(long? courseId, short languageId)
{
ISQUserDataContext db = CreateDataContext();
return new Course(db.Admin_GetCourseById_sp(courseId, false, languageId).FirstOrDefault());
}
and then add a class Course with a constructor accepting the returntype of Admin_GetCourseById_sp to build a nice Course object.
Your
db.Admin_GetCourseById_sp(courseId,false,languageId).FirstOrDefault() line returns a datarow.
(It might return null if there are no data)
Therefore what you can do is this,
you can set each attribute of your
Admin_GetCourseById_spResult result object with the matching value from the returned datarow
i.e result.courseId = row["course_id"].ToString()
{ I assumed that courseId is String in your Admin_GetCourseById_spResult class + the matching db column is course_id.
You have given little data, so could answer only like this. Good Luck !
Related
As far as I knew, Object.GetType() should never return null. (related discussion)
Dapper .Query() return private class DapperRow instances to be treated as dynamic objects. I found a strange thing: DapperRow's .GetType() return null.
Here's the sample code to reproduce the problem. Create a C# project, reference Dapper and open a connection to SQL Server (or other database), use .Query() to execute simple select query and retrieve the first row of result. Use GetType() to get the type of result object, the return value is null.
using (SqlConnection cn = new SqlConnection(csSql))
{
var rec = cn.Query("select getdate() as D").Single();
var t = rec.GetType(); // t == null
Console.WriteLine(t.Name); // null reference exception
}
I suspect that dynamic or private type is the cause of null, so I write my class library for test:
namespace Lib
{
public class Blah
{
public static dynamic SecretObject;
static Blah()
{
SecretObject = new PrivateType();
}
}
class PrivateType
{
}
}
In another project, get the dynamic type static field and call GetType():
dynamic obj = Lib.Blah.SecretObject;
Console.WriteLine(obj.GetType().Name); // "Lib.PrivateType"
According to the test result, even cast private type as dynamic, I still can get the private type information from GetType(), why DapperRow.GetType() return null?
DapperRow is specifically built and utilized within Dapper to provide highly optimized row returns without reiterating header information. This is to help condense the size of the object and reduce redundant data, making it more efficient.
However, it would appear that the StackExchange team took the meta programming even further than a first glance would indicate.
DapperRow implements the System.Dynamic.IDynamicMetaObjectProvide interface, which requires that the GetMetaObject method be implemented:
System.Dynamic.DynamicMetaObject System.Dynamic.IDynamicMetaObjectProvider.GetMetaObject(
System.Linq.Expressions.Expression parameter)
{
return new DapperRowMetaObject(parameter,
System.Dynamic.BindingRestrictions.Empty, this);
}
DapperRowMetaObject is a custom implementation of DynamicMetaObject that essentially hijacks and overrides what methods can be invoked against the dynamic type and what those calls should translate to. In this case, calls to anything other than the DapperRow's IDictionary.Item getter or the DapperRow.SetValue will fail since they are always routed to those two calls, but the value will be defaulted to null for any "get" calls where the target property does not exist in the table.
public bool TryGetValue(string name, out object value)
{
var index = table.IndexOfName(name);
if (index < 0)
{ // doesn't exist
value = null;
return false;
}
...
}
At that point, any methods invoked on a null dynamic value will throw a RuntimeBinderException:
RuntimeBinderException: Cannot perform runtime binding on a null
reference
You can easily test this hypothesis by replacing GetType() with another call that will throw the exact same exception:
var rec = cn.Query("select getdate() as D").Single();
var t = rec.AsEnumerable();
Console.WriteLine(t.ToList());
Keep in mind, the underlying type information of any properties on the dynamic object itself can still be accessed directly:
var rec = cn.Query("select getdate() as D").Single();
var t = rec.D.GetType();
Console.WriteLine(t.Name);
I have a table with a few fields, one of them is a Double type field which can contains null values...
Using ADO and SQLDATAReader I recover that field in a variable. I defined this variable as a: Double, Double?, double, double?... and I got the value (coming from de SQLDataReader) using GetValue (and doing a cast) or using a GetDouble... each one is crashing when the value is null.
The only this is working is defining this variable as a object, but I dont want it. Thinking in advance could be hard times handle this type in my project...
Quote: I have to differentiate the case when this value is 0 or null...
Any idea guys?
Edited:
Object.DoubleValue= (Double?)Datos.GetDouble(1);
Object.doubleValue= (double?)Datos.GetDouble(1);
Not working.
Object.ObjectValue= Datos.GetValue(1);
Working.
Unfortunately there's no out of the box method. But you could tweak it with an extension method like this:
(be aware its just a rough prototype that works in your case, but probably needs some checks and constraints etc)
public static class Helpers
{
public static T GetSmartValue<T>(this SqlDataReader r, int ordinal)
{
dynamic value = r.GetValue(ordinal);
if (value == DBNull.Value)
{
value = null;
return value;
}
return (T) value;
}
}
then in your code
var x = yourReader.GetSmartValue<double?>(1);
I have a class name DB.IFCArray which have plenty of fields in it (name, description etc), I want to implement a function
that goes to the DB.IFCArray.field and do stuff..
public static bool if_is_a(DB.IFCArray object1, string field, string value)
{
if (object1.field == value) // this ofc not working, but hope you get the idea
return true;
return false;
}
You can of course use Reflection
//get the property indicated by parameter 'field'
//Use 'GetField' here if they are actually fields as opposed to Properties
//although the merits of a public field are dubious...
var prop = object1.GetType().GetProperty(field);
//if it exists
if (prop!=null)
{
//get its value from the object1 instance, and compare
//if using Fields, leave out the 'null' in this next line:
var propValue = prop.GetValue(object1,null);
if (propValue==null) return false;
return propValue;
}
else
{
//throw an exception for property not found
}
But as CodeCaster mentioned above, I'd recommend you take a look at your design and see if this is really necessary. What is the bigger picture here? Unless you absolutely 100% will not know the property names until runtime, there's almost always a better way...
I think error is showing due to type error in the if (object1.field == value) statement.
use reflection to get type of the field and compare the value according to the type.
Hope this helps,
Thanks.
I am new to CRM Development. I would like to update the custom field values in addtion to its existing values in the CRM 2011 from my C# application. If the field has some values then it is working fine, but if it null then i am receiving "The given key was not present in the dictionary." error.
The code below is what i am trying to achieve.
IOrganizationService service = (IOrganizationService)serviceProxy;
QueryByAttribute querybyattribute = new QueryByAttribute("salesorder");
querybyattribute.ColumnSet = new ColumnSet(new String[] {
"salesorderid", "new_customefield" });
querybyattribute.Attributes.AddRange("ordernumber");
querybyattribute.Values.AddRange(ordernumber);
EntityCollection retrieved = service.RetrieveMultiple(querybyattribute);
foreach (var c in retrieved.Entities)
{
OrderID = new Guid(c.Attributes["salesorderid"].ToString());
CustomFieldValue = c.Attributes["new_customefield"].ToString();
}
The error occurs because a field with no entered value won't get returned in the context object not the image. Or to put it graspably - you need to check whether a field is amongst the attributes.
It's not sufficient to have declared it and requested it via ColumnSet. It's confusing and annoying (been there myself).
Just of the top of my head, I can think of the following code snippet to manage the issue (without having to set an if clause for every read but also avoiding a bunch of methods - one for each variable type).
private Generic GetEntityValue<Generic>(
Entity entity, String field, Generic substitute = default(Generic))
{
if (entity.Contains(field))
return (Generic)entity[field];
return substitute;
}
edit: Or as an extension method
public static T GetAttributeValue<T> (this Entity e, string propertyName, T defaultValue = default(T))
{
if (e.Contains(propertyName))
{
return (T)e[propertyName];
}
else
{
return defaultValue;
}
}
I have a method private static DataTable ParseTable(HtmlNode table) and sometimes this method has no return value then I want to make return value optional, is it possible ?
I have tried with if condition.But there is error.
How can I make return value optional for the method if possible ?
You can't make the return value optional.
Your two options are to either return a null or an empty DataTable:
return new DataTable();
OR:
return null;
Which one is right? It depends on your application logic and how much null checking you are willing to do in your calling functions.
Update: (following comment)
This is how to return conditionally (assumes a variable called dataTable):
if(gotTable)
{
return dataTable;
}
else
{
return null;
}
That's what null is for. Your method may return no object by returning null.
Keep in mind that returning null may complicate matters for the callers as they must check for null before using the returned reference, so in some cases it may be better to return a Null Object.
You could always return null to indicate that there is no meaningful return value.
If your method is called ParseTable and it fails "Parse" a "Table", then it should throw an exception. The advantage of this is that the exception can give the caller information about why it couldn't parse (html was invalid, unexpected column etc). The problem with returning null is that an unexpected nullreference exception almost never tells you the cause of the problem.
The "right" way to make a method that tries to parse a table, but happily does nothing if no result could be found is:
public bool TryParseTable(HtmlNode table, out DataTable result){
// your code...
if(success)
{
result = //the table you parsed
return true;
}
else
{
result = null;
return false;
}
}
Ok, so "result" could be null after calling this method, but at least the caller is more inclined to use an if statement thanks to the return type and method name.
private static void ParseTable(HtmlNode table, out DataTable data)
{
// do the parse, fill bool gotTable
data = gotTable ? new DataTable() : null;
}
private static void ParseTable(HtmlNode table)
{
ParseTable(table, out null);
}
if caller need table
DataTable data;
ParseTable(table, out data);
if not
ParseTable(table);
EDIT: I can't find how to implement optional out/ref parameters. So maybe it's impossible until .NET 4.0 or fully impossible.