Insert with Linq-to-SQL an object determined through reflection - linq-to-sql

I am trying to populate a row in a table given a key value list
Using DataContext.Mapping I am able to locate the correct table (given a table name) and create a row.
// Look up the table
MetaTable matchedTable = null;
foreach (MetaTable tableMetaData in db.Mapping.GetTables())
{
if (table.Equals(tableMetaData.TableName))
{
matchedTable = tableMetaData;
break;
}
}
if (matchedTable == null)
{
throw new Exception("Invalid table name specified");
}
I then iterate over the row properties and populate the values.
// Iterate through the dictionary and try to match up the keys with column names
foreach (KeyValuePair<string, string> listItem in list)
{
PropertyInfo propertyInfo = rowType.GetProperty(listItem.Key);
if (propertyInfo == null)
{
throw new Exception("Invalid column name specified");
}
// Set the value on the object
try
{
propertyInfo.SetValue(row, Convert.ChangeType(listItem.Value, propertyInfo.PropertyType), null);
}
catch
{
throw new Exception("Value specified cannot be converted to database type");
}
}
I now need to get this row object inserted back into the DB. I have been playing around with db.GetTable<rowType>(); with no luck. Thanks

I was overthinking it
db.GetTable(rowType).InsertOnSubmit(row);
db.SubmitChanges();

Related

Android Development: App crashes As soon as cuursor is called to search for a row in my table

I am quite new to android development, I am making an app in which i need to search a row in my table which has 3 columns Id, Items and User.
In this table I have to search for a particular user and return string Items of that row.
But as soon as I call cursor, the app crashes; why is that? And is there any other way to do this?
public String loadData(String user,Context context)
{
SQLiteDatabase sq = this.getReadableDatabase();
String[] Columns = {C1,C2,C3};
Cursor cr = sq.query(Table2, Columns, null, null, null, null, null);
if (cr.getCount()==0) {
Toast.makeText(context,"Something Is wrong,Not Able to Load",Toast.LENGTH_SHORT).show();
return "";
}
else {
String ans = "";
do {
if (cr.getString(2).equals(user)) {
ans = cr.getString(1);
break;
}
} while(cr.moveToNext());
return ans;
}
You need to move the cursor to a valid row before attempting to read column value with getString() from it. You can move it with e.g. moveToFirst() or moveToNext() that return true when the cursor is pointing to a valid row.
In other words, you need a if (cr.moveToFirst()) before your do-while loop.

Fat-Free-Framework / F3 access a hive variable in a mapper callback

I'm using the Fat Free Framework ORM Mapper functionality to insert a set of records passed from the client in an array. The Mapper function has callbacks to for aftersave which pass an array of keys and the mapper object.
I want to be able to loop through the records and use the mapper to insert the records one by one, storing the inserted record's id in an array ('resultsArray') which is set in the F3 hive in the parent function:
function myFunction (\Base $f3, $params) {
// array of records to insert
$mappedArray = json_decode( $f3->get('BODY'), true );
$f3->set('mapper', new mapper($db,'mytable'));
$mapper = $f3->get('mapper');
// create an array in the hive to store the results of the inserts
$f3->set('resultsArray', array());
// set mapper callbacks
$mapper->aftersave(function($self,$pkeys){
// update the resultsArray in the hive?
});
$recordsInArray = count($mappedArray);
// loop through the array of objects
for ($loop = 0; $loop<$recordsInArray; $loop++){
$newRecord = $mappedArray[$loop];
try{
// clear the mapper down
$mapper->reset();
// set the array in the hive
$f3->set('data', $newRecord );
$mapper->copyFrom('data');
$mapper->save();
} catch(\PDOException $e) {
// do something
exit;
}
}
echo "done";
}
Is there a way to access the resultsArray variable I set in the hive in the aftersave callback?
Thanks
Matt
Are you sure that you need to do all these things to achieve what you want?
To be able to store the IDs of inserted records and put it in the F3's hive, I would do the following:
<?php
function myFunction (\Base $f3, $params) {
// array of records to insert
$mappedArray = json_decode( $f3->get('BODY'), true );
//mapper (no need to put it into hive):
$mapper = new mapper($db,'mytable');
// array with IDs:
$resultsArray = [];
// loop through the array of objects
for ($loop = 0; $loop<count($mappedArray); $loop++){
try{
// clear the mapper down
$mapper->reset();
// map the content (no need to put it in the hive):
$mapper->copyFrom($mappedArray[$loop]);
// insert new record:
$mapper->save();
// get the ID of the inserted record and put it in the array:
$resultsArray[] = $mapper->_id;
} catch(\PDOException $e) {
// do something
exit;
}
}
// put the array of IDs in the hive:
$f3->set("newIDs", $resultsArray);
}
You can access the hive within the aftersave handler with the php use feature:
function myFunction (\Base $f3, $params) {
// ...
$mapper->aftersave(function($self,$pkeys) use($f3) {
$f3->get('resultsArray');
});
}

json C# 7 Tuple Support

I want to get my C#7 tuple property names in my JSON (Newtonsoft.Json) output.
My problem is:
When I want to convert my tuple to JSON format that not support my parameters names.
For example this is my "Test2" method and you can see the JSON output:
public void Test2()
{
var data = GetMe2("ok");
var jsondata = JsonConvert.SerializeObject(data);//JSON output is {"Item1":5,"Item2":"ok ali"}
}
public (int MyValue, string Name) GetMe2(string name)
{
return (5, name + " ali");
}
The JSON output is "{"Item1":5,"Item2":"ok ali"}" but i want "{"MyValue":5,"Name":"ok ali"}";
This is not impossible because I can get property names in runtime:
foreach (var item in this.GetType().GetMethods())
{
dynamic attribs = item.ReturnTypeCustomAttributes;
if (attribs.CustomAttributes != null && attribs.CustomAttributes.Count > 0)
{
foreach (var at in attribs.CustomAttributes)
{
if (at is System.Reflection.CustomAttributeData)
{
var ng = ((System.Reflection.CustomAttributeData)at).ConstructorArguments;
foreach (var ca in ng)
{
foreach (var val in (IEnumerable<System.Reflection.CustomAttributeTypedArgument>)ca.Value)
{
var PropertyNameName = val.Value;
Console.WriteLine(PropertyNameName);//here is property names of C#7 tuple
}
}
}
}
dynamic data = attribs.CustomAttributes[0];
var data2 = data.ConstructorArguments;
}
}
For the specific case here, it is impossible. That's because SerializeObject has no way of finding out where the tuple came from, all it sees is ValueTuple<int, string>.
The situation would be different if you were serializing an object with tuple properties, in which case SerializeObject could use reflection to find the TupleElementNames attributes (even though it currently doesn't).
The short answer it that tuples don't have properties.
A tuple is a bag of values used, mainly, to return multiple values from a method.
They were never intended to model entities.
The only way to solve your problem, if you don't want to create a type for that, is:
public void Test2()
{
var data = GetMe2("ok");
var jsondata = JsonConvert.SerializeObject(new { data.MyValue, data.Name });//JSON output is {"Item1":5,"Item2":"ok ali"}
}

How do I dynamically create an html table given only a table name in entity framework?

My code is more like creating an engine that when passed a table name variable, will construct the table dynamically. This is the code I'm already working on. In my controller,
public ActionResult ViewTable(string tablename)
{
ScsContext context = new ScsContext();
List<string> columnNames = new List<string>();
var html = "<table><thead><tr>";
switch(tablename)
{
case "table1":
columnNames = typeof(table1).GetProperties().Select(a => a.Name).ToList();
foreach(var c in columnNames)
{
html += "<td>" + c.ToString() + "</td>";
}
html += "</tr></thead><tbody>";
var rows = from c in context.table1.ToList()
select c;
foreach(var c in rows)
{
foreach(var p in c.GetType().GetProperties())
{
foreach(var s in columnNames)
{
if(p.Name == s.ToString())
{
// How do I get the value here?
}
}
}
}
break;
// more case statements here based on table names
default:
break;
}
// return empty for now
return new EmptyResult();
}
I was able to loop the names of my columns in my entities, as above, and now constructing my html table based on those values.. but when I need to get the value now, I'm stucked. How do I get the value from my properties above to construct my html table based on table name variable?
And since I have more hundred tables the user want rendered, is there a simpler and more efficient way to do this?
Thanks very much,

Is it possible to skip or ignore a attribute while using Streaming API of Jackson

This is my JSON source. Can we skip the retweeted_status token and move to the next contributors token (not the one inside the retweeted_status token).
Currently the following code goes into the retweeted_status object and parsing each one of them:
jp = jsonF.createJsonParser(strLine);
if (jp.nextToken() != JsonToken.START_OBJECT) {
throw new IOException("Expected data to start with an Object");
}
TwitterEntry result = new TwitterEntry();
// Iterate over object fields:
while (jp.nextToken() != JsonToken.END_OBJECT) {
String fieldName = jp.getCurrentName();
// Let's move to value
jp.nextToken();
if (fieldName.equals("id")) {
result.setId(jp.getLongValue());
} else if (fieldName.equals("text")) {
result.setText(jp.getText());
} else if (fieldName.equals("fromUserId")) {
result.setFromUserId(jp.getIntValue());
} else if (fieldName.equals("toUserId")) {
result.setToUserId(jp.getIntValue());
} else if (fieldName.equals("languageCode")) {
result.setLanguageCode(jp.getText());
} else { // ignore, or signal error?
//Ignoring unrecognized fields
//throw new IOException("Unrecognized field '"+fieldName+"'");
}
}
jp.close();
You should be able to use jp.skipChildren() in your else statement.
ie
...
else {
jp.nextToken(); // go to value token
jp.skipChildren(); // skip if object or array
}
...