I'm trying to load data from DynamoDB.
I use FilterExpression and KeyExpression.
If I search by simple value on the top level everything works fine.
However, when I try to filter records by nested map values, I get 0 records.
CurrentCase is an object, Assignments is Dictionary, Setup is Enum.
Here is my code:
`Expression filterExpression = new ();
filterExpression.ExpressionAttributeNames["#Setup"] = "CurrentCase.Assignments.Setup";
filterExpression.ExpressionAttributeValues[":userId"] = userId;
filterExpression.ExpressionStatement = "#Setup = :userId";`
I tried another way, didn't help. (WHERE CurrentCase.Assignments['Setup'] = 'Id' works in PartyQL):
`Expression filterExpression = new ();
filterExpression.ExpressionAttributeNames["#Setup"] = "CurrentCase.Assignments['Setup']";
filterExpression.ExpressionAttributeValues[":userId"] = userId;
filterExpression.ExpressionStatement = "#Setup = :userId";`
This is how i call query
var queryOperationConfig = new QueryOperationConfig
{
PaginationToken = paginationToken,
Limit = pageSize,
IndexName = GlobalIndexNames.Cases,
KeyExpression = keyExpression,
FilterExpression = filterExpression
};
Search search = _dbContext.GetTargetTable<CaseEntity>().Query(queryOperationConfig);
List<Document> documents = await search.GetNextSetAsync(cancellationToken);
I expect that this request return all records where CurrentCase.Assignments['Setup'] equals userId
Forgive me, im not a .Net coder, but your issue is this:
filterExpression.ExpressionAttributeNames["#Setup"] = "CurrentCase.Assignments.Setup";
You are essentially setting your var #Setup to a String "CurrentCase.Assignments.Setup"
It should be:
ExpressionAttributeNames = new Dictionary<string, string>
{
{ "#CurrentCase", "CurrentCase" },
{ "#Assignments", "Assignments" },
{ "#Setup", "Setup" }
}
filterExpression.ExpressionStatement = "#CurrentCase.#Assignments#Setup = :userId";`
You may need to restructure the example I gave, but you should get the idea.
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);
}
}
I have a Datatable which is being added to List with specific format. Now as per my requirement I do not want to create generic list from a Class while preserving the format of my data but not able to do it. Below is my code
List<Data> datalist = new List<Data>();
for (int i = 0; i < dt.Rows.Count; i++)
{
Data dd1 = new Data();
dd1.ID = Convert.ToString(dt.Rows[i]["ID"]);
dd1.STATUS = Convert.ToString(dt.Rows[i]["Name"]);
dd1.TYPE = Convert.ToString(dt.Rows[i]["TYPE"]);
datalist.Add(dd1);
}
Is there a way to remove dependency of class Data from the above code keeping the format same?
You can use linq query on your dt like below and project your result into anonymous type like.
var datalist = (from r in dt.AsEnumerable()
select new
{
ID = r.Field<string>("ID"),
Name = r.Field<string>("Name"),
TYPE = r.Field<string>("TYPE"),
}).ToList();
If you want to get name for some Id from datalist then.
string name = datalist.Where(x => x.ID == "123").FirstOrDefault()?.Name;
You could use a dictionary in its place. No more Data class dependency, but the same basic data and format!
var datalist = new List<IDictionary<string, string>>();
for (var i = 0; i < dt.Rows.Count; ++i)
{
var data = new Dictionary<string, string>()
{
{ "ID", Convert.ToString(dt.Rows[i]["ID"]) },
{ "STATUS", Convert.ToString(dt.Rows[i]["Name"]) },
{ "TYPE", Convert.ToString(dt.Rows[i]["TYPE"]) }
};
datalist.Add(data);
}
Then you'd just access the values datalist[i]["ID"] instead of datalist[i].ID.
This code helps to retrieve the contact records based on the relation 1:N from the account entity
I want to retrieve the records of another custom entity called company from the account entity however I don't know how to call custom data entities to use it in the RetrieveContact method
- contact is a standard entity and company is a custom entity
PS: the account lookup of the company entity is called cs_accountid
BusinessEntityCollection bec = RetrieveContact(Service, context, ((Key)(Account.Properties["accountid"])).Value.ToString(), "contact", "parentcustomerid");
if (bec.BusinessEntities.Count > 0)
{
foreach (contact c in bec.BusinessEntities)
{
c.parentcustomerid = new Customer();
c.parentcustomerid.type = "account";
c.parentcustomerid.Value = k.Value;
Service.Update(c);
}
}
private BusinessEntityCollection RetrieveContact(ICrmService service, IPluginExecutionContext context, string AccountID, string FromEntityName, string FromAttributeName)
{
// Create the ConditionExpression.
ConditionExpression condition = new ConditionExpression();
condition.AttributeName = "accountid";
condition.Operator = ConditionOperator.Equal;
condition.Values = new string[] { AccountID };
// Create the Link entities
LinkEntity le = new LinkEntity();
le.LinkFromEntityName = FromEntityName;
le.LinkFromAttributeName = FromAttributeName;
le.LinkToEntityName = "account";
le.LinkToAttributeName = "accountid";
// Create the FilterExpression.
FilterExpression filter = new FilterExpression();
// Set the properties of the filter.
filter.FilterOperator = LogicalOperator.And;
filter.AddCondition(condition);
le.LinkCriteria = filter;
// Create the QueryExpression object.
QueryExpression query = new QueryExpression();
// Set the properties of the QueryExpression object.
query.EntityName = FromEntityName;// EntityName.contact.ToString();
query.ColumnSet = new AllColumns();// cols;
query.LinkEntities.Add(le);
//query.AddOrder("lastname", OrderType.Ascending);
BusinessEntityCollection bec = service.RetrieveMultiple(query);
return bec;
}
private DynamicEntity RetournRecord(string entityname, Guid recordid, TargetRetrieveDynamic target, ICrmService Service)
{
target.EntityId = recordid;
target.EntityName = entityname;
RetrieveRequest retrieve = new RetrieveRequest();
retrieve.Target = target;
retrieve.ColumnSet = new AllColumns();
retrieve.ReturnDynamicEntities = true;
// Create a response reference and execute the retrieve request.
RetrieveResponse response1 = (RetrieveResponse)Service.Execute(retrieve);
return (DynamicEntity)response1.BusinessEntity;
}
Thank you for your help and your time!
I know this is old, but the problem with the createquery is due to a typo-> ["cs_accountid") It should end with a square bracket not a round one.
UPDATE:
this solution is for CRM 2011/2013 and not for CRM 4.0:
i never used earlybinding so this is my example for the latebinding (will work for you, too).
using Microsoft.Xrm.Sdk.Client;
...
var service = OrganizationServiceFactory.CreateOrganizationService(PluginExecutionContext.UserId);
using (var context = new OrganizationServiceContext(service))
{
List<Entity> myCompanyRecords = context.CreateQuery("cs_company").Where(o => ((EntityReference)o["cs_accountid").Id.Equals(id)).ToList();
}
the "id" is the Guid of your account-entity-record.
in your method you already have the parameter "service" and "context" so you can just use this:
List<Entity> myCompanyRecords = context.CreateQuery("cs_company").Where(o => ((EntityReference)o["cs_accountid").Id.Equals(id)).ToList();
I'm trying to use an email address to retrieve contact data. I'm already using this but i'm wondering how to extend it so that custom fields can also be returned:
public ContactInfo GetContactByEmail(string email, CrmService service)
{
QueryExpression query = new QueryExpression();
query.EntityName = "contact";
ColumnSet columns = new ColumnSet();
columns.Attributes.Add("contactid");
query.ColumnSet = columns;
query.Criteria = new FilterExpression();
query.Criteria.FilterOperator = LogicalOperator.And;
ConditionExpression condition = new ConditionExpression();
condition.AttributeName = "emailaddress1";
condition.Operator = ConditionOperator.Equal;
condition.Values = new object[] { email.Trim() };
query.Criteria.Conditions.Add(condition);
RetrieveMultipleRequest request = new RetrieveMultipleRequest();
request.Query = query;
ContactInfo contactInfo = new ContactInfo();
RetrieveMultipleResponse response = null;
response = (RetrieveMultipleResponse)service.Execute(request);
foreach (contact cont in response.BusinessEntityCollection.BusinessEntities)
{
contactInfo.contactid = cont.contactid.Value;
//Would also like to retrieve a custom attribute called ContactType (type int)
}
return contactInfo;
}
Any help or examples would be really appreciated. Thank you.
You just need to add additional values to the ColumnSet, e.g.
ColumnSet columns = new ColumnSet();
columns.Attributes.Add("new_contacttype");
Note: The name here should be the schema and not the display.
Examples:
Using Dynamic Entities.
Using the ColumnSet Class.
CrmService.RetrieveMultiple Method.