Convert dynamic to object from dapper Query<dynamic> - c#

Is it possible to convert dynamic variable returned from Dapper.Query to object? Example:
class MyClass
{
public int Id { get; set;}
public string SomeData { get; set; }
}
IEnumerable<dynamic> data = sql.Query<dynamic>(SELECT * FROM MyClassTable");
foreach(var record in data)
{
int parent_id = record.SomeId;
// any simple way to fill MyClass properites from record?
// instead of doing in manually?
MyClass obj = ?
}

any simple way to fill MyClass properites from record?
instead of doing in manually?
No. Unfortunately you'll have to do it manually. The best thing you can do is move the mapping logic to one place so you can re-use it in your data access layer. I usually use extension methods, but you can also use reflection to set matching property names...however, in my personal opinion, I usually use dapper for its performance benefits and using reflection is a bit expensive, for that reason I usually avoid using reflection in these cases.
Is it possible to convert dynamic variable returned from Dapper.Query to object?
Yes. As explained above
I know you probably wanted to simplify your question but I guess it's worth pointing out that the example that you posted doesn't need to return a dynamic object if MyClass represents the records returned by that select query. You could simply do the following...
var data = sql.Query<MyClass>(SELECT * FROM MyClassTable");

Related

Update all Fields passed in object without using replace

I'm writing a wrapper around certain functions of mongodb to enforce certain buisiness policies (such as having a last modified date, a document version &c). These extra fields will not appear in the model and will be irrelevant and transparent to the person implementing against this library. This library will be generic.
Therefore using replaceOne is out of the question.
What I would like is some way of passing all fields in a person passed object to the Update builder - so I can use .Set/.Inc accordingly to add the other fields.
An example to demonstrate what I want is below:
public static async Task UpdatePerson(string name, Person person)
{
var client = new MongoClient("mongodb://localhost:27017");
IMongoDatabase db = client.GetDatabase("test");
IMongoCollection<Person> collection = db.GetCollection<Person>("people");
var query = Builders<Person>.Filter
.Eq("name", name);
var update = Builders<Person>.Update
//Something here - how do I pass my person's properties?
.Set("lastModified", DateTime.Now)
.Inc("version",1);
await collection.UpdateOneAsync(query, update );
}
//--
//In real life this'll work for other types, this is for demonstration only
public class Person
{
public string name {get;set;}
public string surname {get;set;}
}
So how can I go about this, without, for instance, looping through properties using Reflection?
Not sure if you are able to do this but the Mongodb Driver provides something called [BsonExtraElements].
public class Person
{
public string name {get;set;}
public string surname {get;set;}
[BsonExtraElements]
public Dictionary<string,object> AdditionalFields { get; set; }
}
What will happen is that anything that cant be serialized to the model will be filled into that dictionary, no matter the type. You can add to it as well and remove.
This will add no additional overhead to your database, The only downside to this is that querying this dictionary is somewhat not a great experience as you may need to cast specific keys to their relevant expected types.
If this is not viable I suggest the BSON approach recommended by Simon.

Casting contents of an indexer's returned collection?

I have a table/row/column data structure setup. There is a string-based indexer in the DtaTable class to return DtaRows, and another on the DtaRow class to return DtaColumns. So you can write things like...
return theTables["tablename"]["rowidentifier"]["columnname"];
In actuality, the objects inside the tables are not DtaRows, but one of about three dozen subclasses, like InflationRow and CurrencyRow. Each table contains only objects of those types, so for instance...
theTables["Inflations"]["General"];
always returns an InflationRow.
Now to make this easier to access from C#, I have a bunch of methods at a higher level like...
public DtaTable Inflations { get {return pTables["Inflations"];} }
Now the problem I'd like to solve is that when someone calls one of these methods, they don't get an InflationRow, because DtaTable has DtaRows. So for instance...
MyInfRow = Inflations["General"];
returns a DtaRow. So I have to cast all the time...
MyInfRow = (InflationRow)Inflations["General"];
I want to get rid of all the casting.
The only solution I have found so far is to make 36 new subclasses of the table object, each overriding the indexer return type. This seems worse than the casting.
Is there some simpler way to do this?
It you know that callers are only primarily going to use another indexer, you can introduce a generic class providing that:
public class SpecializedTable<T>
{
private readonly DtaTable table;
// Just in case anyone really wants this
public DtaTable Table { get; }
public SpecializedTable(DtaTable table)
{
this.table = table;
}
public T this[string row] { get { return (T) (object) table[row]; } }
}
As an aside, these DtaTable etc names feel annoying unpronounceable / easily confusable with the .NET DataTable classes. If you're in a position to rename them, I'd suggest you do so.
Then your Inflations property can be:
public SpecializedTable<InflationRow> Inflations
{
get
{
return new SpecializedTable<InflationRow>(pTables["Inflations"]);
}
}
You may want to cache this to avoid creating a new object each time you call the property though.
At that point, this code: Inflations["General"] will perform the cast appropriately for you.
Use as instead of direct cast. If casting is valid it will return the instance, otherwise it will stay as NULL.
public MyInfRow Inflations { get {return pTables["Inflations"] as MyInfRow } }

How to avoid boxing and if or Switch statements

Suppose I have following object:
object[] objs = new object[3]{ "this is sample string", 42L, 1};
and I want to do something to the individual objects in the array like
foreach (object o in objs)
{
/// logic here
mylogic();
}
Now mylogic() will only take object parameters so there is boxing going on, but we require to be able to do something based on the type of the object, so we would do something like :
public void dosomething(object obj)
{
// one way
if(obj.GetType() == typeof(string))
{
// string specific something
}
// another way
if(obj is long)
{
// long specific something
}
}
Well it's ugly and non performance, is there a better way possible using generics or any other way?
Your values are already boxed, because they are stored in an object[]. So no additional boxing takes place when you pass them to a method taking an object argument.
The object[] is where I would aim my focus - is it really necessary to represent your data like that? Do you really not know their structure? It would be preferable to define a class (or a structure) to hold your data, and also to contain the methods that act on the data - then you know a type of each field or property at design and compile time, and you can use this information in further code. In your case that might look like:
class Container
{
public string StringProperty { get; set; }
public long LongProperty { get; set; }
public int IntProperty { get; set; }
public void DoSomething()
{
// string specific something with StringProperty
// long specific something with LongProperty
// int specific something with IntProperty
}
}
That way you begin to encapsulate your data and make sure it is located close to the logic that uses them. Even better might be to make the properties into private readonly fields, so they are not even visible to the outside.
You could try looking into using the dynamic keyword in C# 4.0 and later and see if that helps you. It would be better to define your own class and make properties of the different types and just use those instead.
The memory overhead would be minimal and you'd avoid all the boxing penalties.
IMO, in such cases one should ask the question: is there anything wrong with the code design? What is the idea of the array containing different types of objects? What do they represent? May be you need a separate class that holds these different objects...

Linq-to-sql query int array in entity

Let's say we have a class that has an int array as one of its properties.
public MyClass
{
public int Id { get; set; }
public string Name { get; set; }
public int[] Values { get; set; }
}
We store it in the db using entity framework. What I've noticed is that EF turns the Values property into a varchar(max).
Now, what we would want to do, is to query the database and return records for which 'Values' contains the given int parameter.
public List<MyClass> Search(int valueToSearch)
{
return context.MyClasses.Where(x => x.Values.Contains(valueToSearch)).ToList();
}
However, this throws an exception that linq-to-sql does not support the contains command.
I also tried Where(x => x.Values.Any(y => y == valueToSearch)) but that throws the same exception.
I suppose it has something to do with the fact that EF turns the array into a varchar so it won't be able to use the contains statement or something. Maybe a seperate table for the Values would solve the problem, but it looks kinda stupid to create a class that only has one integer property?
Is there a better way to solve this?
I found a lot of examples doing the opposite (the SQL IN statement) but that's not what we're looking for. We only have one integer as parameter, but several integers in our entity.
We're using EF5 with .NET 4.0.
Thanks!
Edit
It seems the varchar is a string we create ourselves. As it was code I didn't write myself, I wasn't aware of that. That string ofcourse gets translated into a varchar.
So now the question changes into something like 'What's the best way to store arrays of primitive types?' and that question has already been answered many times here on SO (one of them is provided in the comments).
Do the query outside of linq to entities: (you have to pull in all the rows)
public List<MyClass> Search(int valueToSearch)
{
var c = context.MyClasses.ToList(); // cache
return c.Where(x => x.Values.Contains(valueToSearch));
}
EDIT: If you are currently manually converting the array of integers into a string, then change your class property from an array of integers to a string.
Although, I recommend a new table. An array of integers as a string in a db fields smells a little.

Fluent NHibernate, Referencing Hard-Coded C# Method

I have some functionality that needs to be 'selectable' as an option for certain objects in my database, but the actual code behind each method is far too complicated to be serialized into a database. They also cannot be SQL Stored Procedures.
So basically, I have a static List<T> of these functions. Is there a standard way of associating these with objects in my database? For instance..
var functions = new static List<Omega>{
new Omega {
Id = 1, // this would be useful to a database, but nothing really sets it.
Name = "Some Name", // this isn't useful. It's a string literal
Function = // this may be a Method, or a Lambda Expression, or something else.
}
};
class Psi {
Guid Id { get; set; }
Omega Omega { get; set; } // how can I keep a hard-reference here?
}
Ok, I am not sure if I got it correctly. Delegates are serializable and therefore they can be stored into a database, e.g. using NH. There are some limitation but serializing delegates is an adventurous journey anyway:).
If it is not a viable way, then you could try to implement all your "functions" as static methods. Class and method name can be stored in a table column and invoked via reflection.

Categories