Pull full dynamodb table with document model - c#

string tableName = _awsSettings.TableSettings.Table + _awsSettings.TableSettings.Suffix;
Table table = Table.LoadTable(_amazonDynamoDb, tableName);
DocumentBatchGet batch = table.CreateBatchGet();
await batch.ExecuteAsync();
List<Document> results = batch.Results;
return results.As<Lab>();
The above code returns 0 results. I am hoping to return the entire table.
How can I, using the document model (Table.LoadTable), pull the entire table?

The Table.LoadTable() method returns a Table object, which is basically a wrapper for the DynamoDB client. This object does not contain any of the data that is in the actual table in AWS.
To read all of the items in a table, you need to use the Table.Scan() method. Here is some sample code that uses scan to dump the contents of a table to the standard output.
private static void DumpTable(Table table)
{
ScanFilter scanFilter = new ScanFilter();
Search search = productCatalogTable.Scan(scanFilter);
List<Document> documentList = new List<Document>();
do
{
documentList = search.GetNextSet();
foreach (var document in documentList)
PrintDocument(document);
} while (!search.IsDone);
}
private static void PrintDocument(Document document)
{
// count++;
Console.WriteLine();
foreach (var attribute in document.GetAttributeNames())
{
string stringValue = null;
var value = document[attribute];
if (value is Primitive)
stringValue = value.AsPrimitive().Value.ToString();
else if (value is PrimitiveList)
stringValue = string.Join(",", (from primitive
in value.AsPrimitiveList().Entries
select primitive.Value).ToArray());
Console.WriteLine("{0} - {1}", attribute, stringValue);
}
}

This C# code is to pull records from a dynamodb table having different guid's using BatchGet or CreateBatchGet
string tablename = "AnyTableName"; //table whose data you want to fetch
var BatchRead = ABCContext.Context.CreateBatchGet<ABCTable>(
new DynamoDBOperationConfig
{
OverrideTableName = tablename;
});
foreach(string Id in IdList) // in case you are taking string from input
{
Guid objGuid = Guid.Parse(Id); //parsing string to guid
BatchRead.AddKey(objGuid);
}
await BatchRead.ExecuteAsync();
var result = BatchRead.Results;
// ABCTable is the table modal which is used to create in dynamodb & data you want to fetch

Related

"Cannot access child value on Newtonsoft.Json.Linq.JValue"

My JSON File
{"data":
[
{"id":"1","user_code":"C016482","name":"CART 1","details":"[{\"Id\":15476,\"Name2\":\"AQUAFRESHIG TEETH (6+)\",\"SalesPriceVM\":250,\"DiscountPercentVM\":0,\"product_quantity\":3,\"Image_Url\":\"http:\\\/\\\/182.160.118.235:8099\\\/api\\\/ImageFile\\\/GetImage?enumEntityType=2&entityId=15476\"},{\"Id\":22514,\"Name2\":\"BABE ANTI OILY DANDRUFF SHAMPOO 250 ML\",\"SalesPriceVM\":1800,\"DiscountPercentVM\":0,\"product_quantity\":1,\"Image_Url\":\"http:\\\/\\\/182.160.118.235:8099\\\/api\\\/ImageFile\\\/GetImage?enumEntityType=2&entityId=22514\"},{\"Id\":19886,\"Name2\":\"ALOE VERA GEL\",\"SalesPriceVM\":1674,\"DiscountPercentVM\":0,\"product_quantity\":1,\"Image_Url\":\"http:\\\/\\\/182.160.118.235:8099\\\/api\\\/ImageFile\\\/GetImage?enumEntityType=2&entityId=19886\"}]","created_at":"2020-05-20 11:52:49","updated_at":"2020-05-20 11:52:49"},
{"id":"2","user_code":"C020552","name":"CART1","details":"[{\"Id\":15480,\"Name2\":\"LISTERINE MOUTHWASH ORIGINAL 500 ML\",\"SalesPriceVM\":460,\"DiscountPercentVM\":0,\"product_quantity\":1,\"Image_Url\":\"http:\\\/\\\/182.160.118.235:8099\\\/api\\\/ImageFile\\\/GetImage?enumEntityType=2&entityId=15480\"},{\"Id\":20572,\"Name2\":\"SAVLON ACTIVE HAND WASH RF 1000ML\",\"SalesPriceVM\":230,\"DiscountPercentVM\":0,\"product_quantity\":1,\"Image_Url\":\"http:\\\/\\\/182.160.118.235:8099\\\/api\\\/ImageFile\\\/GetImage?enumEntityType=2&entityId=20572\"},{\"Id\":25899,\"Name2\":\"HANDISANITTIZER 200ML SOLUTION\",\"SalesPriceVM\":100,\"DiscountPercentVM\":0,\"product_quantity\":2,\"Image_Url\":\"http:\\\/\\\/182.160.118.235:8099\\\/api\\\/ImageFile\\\/GetImage?enumEntityType=2&entityId=25899\"}]","created_at":"2020-05-21 01:43:10","updated_at":"2020-05-21 01:43:10"},
{"id":"3","user_code":"C020557","name":"PR 1","details":"[{\"Id\":13319,\"Name2\":\"EXIUM CAPS 20\",\"SalesPriceVM\":8.5,\"DiscountPercentVM\":0,\"product_quantity\":10,\"Image_Url\":\"http:\\\/\\\/182.160.118.235:8099\\\/api\\\/ImageFile\\\/GetImage?enumEntityType=2&entityId=13319\"},{\"Id\":16432,\"Name2\":\"DOMIDON 10MG TAB\",\"SalesPriceVM\":2,\"DiscountPercentVM\":0,\"product_quantity\":10,\"Image_Url\":\"http:\\\/\\\/182.160.118.235:8099\\\/api\\\/ImageFile\\\/GetImage?enumEntityType=2&entityId=16432\"},{\"Id\":19480,\"Name2\":\"ALOCAP SOFT CAP\",\"SalesPriceVM\":6,\"DiscountPercentVM\":0,\"product_quantity\":10,\"Image_Url\":\"http:\\\/\\\/182.160.118.235:8099\\\/api\\\/ImageFile\\\/GetImage?enumEntityType=2&entityId=19480\"},{\"Id\":23223,\"Name2\":\"CYNTA 100MG TAB.\",\"SalesPriceVM\":25,\"DiscountPercentVM\":0,\"product_quantity\":40,\"Image_Url\":\"http:\\\/\\\/182.160.118.235:8099\\\/api\\\/ImageFile\\\/GetImage?enumEntityType=2&entityId=23223\"},{\"Id\":2063,\"Name2\":\"MARLOX PLUS-200 ML-SUSPENSION\",\"SalesPriceVM\":110,\"DiscountPercentVM\":0,\"product_quantity\":1,\"Image_Url\":\"http:\\\/\\\/182.160.118.235:8099\\\/api\\\/ImageFile\\\/GetImage?enumEntityType=2&entityId=2063\"}]","created_at":"2020-05-21 07:30:29","updated_at":"2020-05-21 07:30:29"},
]
}
I am trying to read "details". In details, there are three objects I am trying to read Id,product_quantity of each object and insert them into the db table.
MY Code
public void PostSaveCartItemData()
{
var contents = File.ReadAllText("saved_carts.json");
dynamic jsonResponse = JsonConvert.DeserializeObject(contents);
int i = 0;
using (MainDataContext ctx = new MainDataContext())
{
List<SavedCartItem> list = new List<SavedCartItem>();
foreach (var item in jsonResponse.data)
{
var productId = item.details[i].Id;
var qty = item.details[i].product_quantity;
i++;
SavedCartItem entity = new SavedCartItem()
{
ProductId = productId,
Qty = qty ,
};
list.Add(entity);
}
ctx.SavedCartItems.AddRange(list);
ctx.SaveChanges();
}
}
Your kind help will be highly appreciated.
The details property is JSON encoded as a string, you need to further deserialise that value if you want to use it. Also, you should avoid using dynamic, there's no need. For example:
var jsonResponse = JObject.Parse(Json);
foreach (var item in jsonResponse["data"])
{
var detailsJson = item["details"];
var details = JArray.Parse(detailsJson.ToString());
foreach(var detail in details)
{
var productId = detail["Id"];
var qty = detail["product_quantity"];
Console.WriteLine(productId);
Console.WriteLine(qty);
}
}

UWP - Compare data on JSON and database

I have a database called ebookstore.db as below:
and JSON as below:
I want when slug on JSON is not the same as a title in the database, it will display the amount of data with a slug on JSON which is not same as a title in the database in ukomikText.
Code:
string judulbuku;
try
{
string urlPath1 = "https://...";
var httpClient1 = new HttpClient(new HttpClientHandler());
httpClient1.DefaultRequestHeaders.TryAddWithoutValidation("KIAT-API-KEY", "....");
var values1 = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("halaman", 1),
new KeyValuePair<string, string>("limit", 100),
};
var response1 = await httpClient1.PostAsync(urlPath1, new FormUrlEncodedContent(values1));
response1.EnsureSuccessStatusCode();
if (!response1.IsSuccessStatusCode)
{
MessageDialog messageDialog = new MessageDialog("Memeriksa update Komik gagal", "Gangguan Server");
await messageDialog.ShowAsync();
}
string jsonText1 = await response1.Content.ReadAsStringAsync();
JsonObject jsonObject1 = JsonObject.Parse(jsonText1);
JsonArray jsonData1 = jsonObject1["data"].GetArray();
foreach (JsonValue groupValue in jsonData1)
{
JsonObject groupObject = groupValue.GetObject();
string id = groupObject["id"].GetString();
string judul = groupObject["judul"].GetString();
string slug = groupObject["slug"].GetString();
BukuUpdate file1 = new BukuUpdate();
file1.ID = id;
file1.Judul = judul;
file1.Slug = slug;
List<String> title = sqlhelp.GetKomikData();
foreach (string juduldb in title)
{
judulbuku = juduldb.Substring(juduldb.IndexOf('.') + 1);
if (judulbuku != file1.Slug.Replace("-", "_") + ".pdf")
{
BukuData.Add(file1);
ListBuku.ItemsSource = BukuData;
}
else
{
ukomikText.Text = "belum tersedia komik yang baru";
ukomikText.Visibility = Visibility.Visible;
}
}
}
if (ListBuku.Items.Count > 0)
{
ukomikText.Text = BukuData.Count + " komik baru";
ukomikText.Visibility = Visibility.Visible;
jumlahbuku = BukuData.Count;
}
else
{
ukomikText.Text = "belum tersedia komik yang baru";
ukomikText.Visibility = Visibility.Visible;
}
public static List<String> GetKomikData()
{
List<String> entries = new List<string>();
using (SqliteConnection db =
new SqliteConnection("Filename=ebookstore.db"))
{
db.Open();
SqliteCommand selectCommand = new SqliteCommand
("SELECT title FROM books where folder_id = 67", db);
SqliteDataReader query = selectCommand.ExecuteReader();
while (query.Read())
{
entries.Add(query.GetString(0));
}
db.Close();
}
return entries;
}
BukuUpdate.cs:
public string ID { get; set; }
public string Judul { get; set; }
public string Slug { get; set; }
I have a problem, that is when checking slugs on JSON, then the slug that is displayed is the first slug is displayed repeatedly as much data in the database, after that show the second slug repeatedly as much data on the database, and so on, as below:
How to solve it so that slug on JSON is not displayed repeatedly (according to the amount of data on JSON)?
The problem is that you have two nested foreach loops. What the code does in simplified pseudocode:
For each item in JSON
Load all rows from DB
And for each loaded row
Check if the current JSON item matches the row from DB and if not, output
As you can see, if you have N items in the JSON and M rows in the database, this inevitably leads to N*M lines of output except for those rare ones where the JSON item matches a specific row in database.
If I understand it correctly, I assume that you instead want to check if there is a row that matches the JSON item and if not, output it. You could do this the following way:
List<String> title = sqlhelp.GetKomikData();
HashSet<string> dbItems = new HashSet<string>();
foreach (string juduldb in title)
{
judulbuku = juduldb.Substring(juduldb.IndexOf('.') + 1);
dbItems.Add( judulbuku );
}
...
foreach ( JsonValue groupValue in jsonData1 )
{
...
//instead of the second foreach
if ( !dbItems.Contains( file1.Slug.Replace("-", "_") + ".pdf" ) )
{
//item is not in database
}
else
{
//item is in database
}
}
Additional tips
Avoid calling GetKomikData inside the foreach. This method does not have any arguments and that means you are just accessing the database again and again without a reason, which takes time and slows down the execution significantly. Instead, call GetKomikData only once before the first foreach and then just use title variable.
Don't assign ItemsSource every time the collection changes. This will unnecessarily slow down the UI thread, as it will have to reload all the items with each loop. Instead, assign the property only once after the outer foreach
write your code in one language. When you start mixing variable names in English with Indonesian, the code becomes confusing and less readable and adds cognitive overhead.
avoid non-descriptive variable names like file1 or jsonObject1. The variable name should be clear and tell you what it contains. When there is a number at the end, it usually means it could be named more clearly.
use plurals for list variable names - instead of title use titles

DataAdapter .Update does not update back table

my problem is very common, but I have not found any solution.
This is my code:
public async Task<QueryResult> RollbackQuery(ActionLog action)
{
var inputParameters = JsonConvert.DeserializeObject<Parameter[]>(action.Values);
var data = DeserailizeByteArrayToDataSet(action.RollBackData);
using (var structure = PrepareStructure(action.Query, action.Query.DataBase, inputParameters))
{
//_queryPlanner is the implementor for my interface
return await _queryPlanner.RollbackQuery(structure, data);
}
}
I need to load DataTable (from whereever) and replace data to database. This is my Rollback function. This function use a "CommandStructure" where I've incapsulated all SqlClient objects. PrepareStructure initialize all objects
//_dataLayer is an Helper for create System.Data.SqlClient objects
//ex: _dataLayer.CreateCommand(preSelect) => new SqlCommand(preSelect)
private CommandStructure PrepareStructure(string sql, string preSelect, DataBase db, IEnumerable<Parameter> inputParameters)
{
var parameters = inputParameters as IList<Parameter> ?? inputParameters.ToList();
var structure = new CommandStructure(_logger);
structure.Connection = _dataLayer.ConnectToDatabase(db);
structure.SqlCommand = _dataLayer.CreateCommand(sql);
structure.PreSelectCommand = _dataLayer.CreateCommand(preSelect);
structure.QueryParameters = _dataLayer.CreateParemeters(parameters);
structure.WhereParameters = _dataLayer.CreateParemeters(parameters.Where(p => p.IsWhereClause.HasValue && p.IsWhereClause.Value));
structure.CommandBuilder = _dataLayer.CreateCommandBuilder();
structure.DataAdapter = new SqlDataAdapter();
return structure;
}
So, my function uses SqlCommandBuilder and DataAdapter to operate on Database.
PreSelectCommand is like "Select * from Purchase where CustomerId = #id"
The table Purchase has one primaryKey on ID filed
public virtual async Task<QueryResult> RollbackQuery(CommandStructure cmd, DataTable oldData)
{
await cmd.OpenConnectionAsync();
int record = 0;
using (var cmdPre = cmd.PreSelectCommand as SqlCommand)
using (var dataAdapt = new SqlDataAdapter(cmdPre))
using (var cmdBuilder = new SqlCommandBuilder(dataAdapt))
{
dataAdapt.UpdateCommand = cmdBuilder.GetUpdateCommand();
dataAdapt.DeleteCommand = cmdBuilder.GetDeleteCommand();
dataAdapt.InsertCommand = cmdBuilder.GetInsertCommand();
using (var tbl = new DataTable(oldData.TableName))
{
dataAdapt.Fill(tbl);
dataAdapt.FillSchema(tbl, SchemaType.Source);
tbl.Merge(oldData);
foreach (DataRow row in tbl.Rows)
{
row.SetModified();
}
record = dataAdapt.Update(tbl);
}
}
return new QueryResult
{
RecordAffected = record
};
}
I Execute the code and I don't have any errors, but the data are not updated.
variable "record" contain the right number of modified (??) record, but..... on the table nothing
can someone help me?
EDIT 1:
With SQL Profiler I saw that no query is executed on DB. Only select query on .Fill(tbl) command.
EDIT 2:
Now I have made one change:
tbl.Merge(oldData) => tbl.Merge(oldData, true)
so I see perform the expected query but, with reversed parameters.
UPDATE Purchase SET price=123 where id=6 and price=22
instead of
UPDATE Purchase SET price=22 where id=6 and price=123

filtered Query for objectContext Using Linq to SQL

i have tried to search some examples about my approach but all questions was not close enough to what i was trying to achieve .
for the TLDR sake , Question is : how do i make it work as in plain sql query?
using c# - Winforms with SqlCompact4 and Linq to SQL
my scenario involves a form with all the relevant Db table columns as availble filters to query
and then on text change event of each filtertextbox as a filter, the datasource of the gridview updates accordingly
and because i allow filtered search via many of them columns i was trying to avoid use of some extra
lines of code.
so lets say we only concentrate on 4 columns
custID, name, email, cellPhone
each has its corresponding TextBox.
i am trying to make a query as follows :
first i systematically collect all Textbox into a List
var AllFormsSearchFiltersTBXLst = new List<TextBox>();
code that collects all tbx on current form
var AllFormsSearchFiltersTBXLst = [currentFormHere].Controls.OfType<TextBox>();
so now i have all of textboxes as filters regardless if they have any value
then check who has some value in it
forech textbox in this filters textboxes if text length is greater than zero
it means that current filter is active
then.. a second list AllFormsACTIVESearchfiltersTBXLst will contain only active filters
what i was trying to achieve was in same way i didn't have to specify each of textbox objects
i just looped through each of them all as a collection and didn't have to specify each via it's id
now i want to make a filter on a dbContext using only those active filters
so i will not have to ask if current tbxName is email
like
query = db.Where(db=>db.email.Contains(TbxEmail.Text));
and again and again for each of 10 to 15 columns
what i have got so far is nothing that implements what i was heading to.
using (SqlCeConnection ClientsConn = new SqlCeConnection(ConfigurationManager.ConnectionStrings["Conn_DB_RCL_CRM2014"].ConnectionString))
{
System.Data.Linq.Table<ContactsClients> db = null;
// get all column names from context
var x =(System.Reflection.MemberInfo[]) typeof(ContactsClients).GetProperties();
using (DB_RCL_CRM2014Context Context = new DB_RCL_CRM2014Context(ClientsConn))
{
if (!Filtered)
db = Context.ContactsClients;//.Where(client => client.Name.Contains("fler"));
else
{
db = Context.ContactsClients;
// filters Dictionary contains the name of textBox and its value
// I've named TBX as Columns names specially so i could equalize it to the columns names when needed to automate
foreach (KeyValuePair<string,string> CurFltrKVP in FiltersDict)
{
foreach (var memberInfo in x)
{
// couldn't find out how to build the query
}
}
}
BindingSource BS_Clients = new BindingSource();
BS_Clients.DataSource = db;
GV_ClientInfo_Search.DataSource = BS_Clients;
what i normally do when working with plain sql is
foreach textbox take its value and add it into a string as filter
var q = "where " ;
foreach(tbx CurTBX in ALLFILTERTBX)
{
q +=CurTBX.Name +" LIKE '%" + CurTBX.Text + "%'";
// and some checking of last element in list off cores
}
then pass this string as a filter to the main select query ... that simple
how do i make it work as in plain sql query?
I think that you're trying to get the property of db dynamically, like: db.email according to the looped name of your textbox (here 'email'). However, I recommend you to do it some other way. I'd make a switch for each type of the property, like: email, name etc. Something like this:
// Create a list for the results
var results = new List<YourDBResultTypeHere>();
foreach(tbx CurTBX in ALLFILTERTBX)
{
switch(CurTBX.Name) {
case "email":
results.AddRange(db.Where(db => db.email.Contains(tbx.Text)).ToList());
break;
case "name":
results.AddRange(db.Where(db => db.name.Contains(tbx.Text)).ToList());
break;
}
}
try this
void UpdateGridViewData(bool Filtered=false, Dictionary<string,string> FiltersDict = null)
{
using (SqlCeConnection ClientsConn = new SqlCeConnection(ConfigurationManager.ConnectionStrings["Conn_DB_RCL_CRM2014"].ConnectionString))
{
System.Data.Linq.Table<ContactsClients> db = null;
IEnumerable<ContactsClients> IDB = null;
BindingSource BS_Clients = new BindingSource();
System.Reflection.MemberInfo[] AllDbTblClientsColumns = (System.Reflection.MemberInfo[])typeof(ContactsClients).GetProperties();
using (DB_RCL_CRM2014Context Context = new DB_RCL_CRM2014Context(ClientsConn))
{
if (!Filtered)
{
db = Context.ContactsClients;
BS_Clients.DataSource = db;
}
else
{
string fltr = "";
var and = "";
if (FiltersDict.Count > 1) and = "AND";
for (int i = 0; i < FiltersDict.Count; i++)
{
KeyValuePair<string, string> CurFltrKVP = FiltersDict.ElementAt(i);
if (i >= FiltersDict.Count-1) and = "";
for (int j = 0; j < AllDbTblClientsColumns.Length; j++)
{
if (AllDbTblClientsColumns[j].Name.Equals(CurFltrKVP.Key))
{
fltr += string.Format("{0} Like '%{1}%' {2} ", AllDbTblClientsColumns[j].Name, CurFltrKVP.Value, and);
}
}
}
try
{
IDB = Context.ExecuteQuery<ContactsClients>(
"SELECT * " +
"FROM ContactsCosmeticsClients " +
"WHERE " + fltr
);
BS_Clients.DataSource = IDB;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
GV_ClientInfo_Search.DataSource = BS_Clients;
}
}
}

Creating SQL table using C#

I would like to create two SQL tables using C#, within a loop. Each table is different, and has its column names stored in an array. Each array of column names is actually obtained from the header of a csv file.
### fnames is an array of file paths (2 csv files)
foreach string f in fnames)
{
## snip
using (StreamReader rdr = new StreamReader(f))
{
string header = read.line(); ## This is the array of table columns
}
string tab = Path.GetFileNameWithoutExtension(f);
string query = #"create table "+ tab + ..."; #I am not sure how to write the column names and types dynamically
}
Imagine that:
The columns for table 1 are : Date (datetime), Value (int)
The columns for table 2 are : Date (datetime), ID (varchar(255)), Return (int)
Note that the two tables have different columns with different types.
Would you have any suggestion as to how to achieve this?
Thank you!
You should break the problem apart, first you need to get a list of objects that define your column headers, after you have that you can loop over that list and build the query.
class HeaderInfo
{
public HeaderInfo(string header)
{
throw new NotImplementedException("Parse out your header info here and populate the class")
}
public string Name {get; private set;}
public string TypeInfo {get; private set;}
}
private List<HeaderInfo> ParseHeader(string header)
{
var headerInfo = new List<HeaderInfo>();
string[] headerItems = //Split your header line in to indvidual items some how
foreach(headerItem in headerItems)
{
headerInfo.Add(new HeaderInfo(headerItem));
}
return headerInfo;
}
private string TableString(List<HeaderInfo> headerInfo)
{
StringBuilder sb = new StringBuilder();
foreach(var info in headerInfo)
{
sb.AppendFormat("{0} {1}, ", info.Name, info.TypeInfo);
}
sb.Remove(sb.Length -2, 2); //Remove the last ", "
return sb.ToString();
}
private void YourMethod(string[] fnames)
{
### fnames is an array of file paths (2 csv files)
foreach string f in fnames)
{
## snip
List<HeaderInfo> headerInfo;
using (StreamReader rdr = new StreamReader(f))
{
string headerLine = read.line(); ## This is the array of table columns
headerInfo = ParseHeader(headerLine);
}
string tab = Path.GetFileNameWithoutExtension(f);
string query = String.Format(#"create table [{0}] ({1})", tab, TableString(headerInfo));
}
}

Categories

Resources