How to update multiple entities with file import in mvc5 - c#

I have a table with user data. I call it 'clients'.
I want to import an excel file where I have more data for them, phone number address etc.
My controller looks like this:
foreach (DataRow row in table.Rows)
{
string email = row["email"].ToString();
Clients clients = db.Clients.Find(email);
var lea = this.db.Clients.Find(email.ToString());
clients.PromoCode = row["AFF"].ToString();
clients.workerId = Convert.ToInt16(row["workersid"]);
clients.Rentetiion = Convert.ToInt16(row["Rentetiion"]);
clients.Contof = row["login"].ToString();
clients.Company = row["Company"].ToString();
clients.Phone = row["Phone"].ToString();
db.Entry(clients).State = EntityState.Modified;
}
db.savechanges
I want to filter by email and update the data on the database, but I get this error:
The argument types 'Edm.Int32' and 'Edm.String' are incompatible for this operation. Near WHERE predicate
Any ideas?

Related

Setting table parameter in BAPI fails

So, this is my first time doing this and sending an structure to a BAPI that was created by someone else, the BAPI works, Ive tried it in SAP, but now, we need our master system to use it.
This is the structure:
The in values has 3 values...
Ok, so I can connect correctly and get the information, but I am getting an error, and I think this is due to the structure being prepared before being sent...
Here is the code:
public string SendASFEmail(string id, string tipo, string correo)
{
string idCompuesto = "0000" + id;
SAPConnection sapConnection = new SAPConnection();
RfcDestination rfcDes = sapConnection.getRfcDestination(sapConnection);
RfcRepository rfcRep = rfcDes.Repository;
IRfcFunction fun = rfcRep.CreateFunction("ZSLCM_UPDATE_EMAIL");
//Create the structure with id, tipo and correo
IRfcTable tablaEntrada = fun.GetTable("T_CORREOS_IN");
//Assign parameters
RfcStructureMetadata stru = rfcRep.GetStructureMetadata("T_CORREOS_IN");
IRfcStructure datos = stru.CreateStructure();
datos.SetValue("ZFKK_FAM", idCompuesto);
datos.SetValue("BPKI", tipo);
datos.SetValue("SMTP_ADDR", correo);
tablaEntrada.Append(datos);
fun.SetValue("T_CORREOS_IN", tablaEntrada);
// RUN
fun.Invoke(rfcDes);
//Success and get the out table which contains the same parameters plus message in column #4
IRfcTable tablaSalida = fun.GetTable("T_CORREOS_OUT");
DataTable dtMessages = GetDataTableFromRFCTable(tablaSalida); //this is to take the out structure and just get the string
string respuesta = dtMessages.Rows[0][3].ToString();
return respuesta;
}
And I keep getting the error:
Additional information: metadata for StructureOnly T_CORREOS_IN not available: NOT_FOUND: No active nametab exists for T_CORREOS_IN
Your problem is in the statement:
RfcStructureMetadata stru = rfcRep.GetStructureMetadata("T_CORREOS_IN");
API function GetStructureMetadata( ) reads SAP repository (!) structure and not parameters of RFC module, hence is the error.
For filling RFC table you need smth like this:
IRfcFunction fn = repo.CreateFunction("ZSLCM_UPDATE_EMAIL");
var correos = fn.GetTable("T_CORREOS_IN");
foreach (ListViewItem lvi in correos.Items)
{
//Create new correos row
correos.Append();
//Populate current row with data from list
correos.SetValue("ZFFK_FAM", lvi.SubItems[0].Text);
correos.SetValue("BKPI", lvi.SubItems[1].Text);
correos.SetValue("SMTP_ADDR", lvi.SubItems[2].Text);
}
Here is the reference answer also with .Net dataTable type sample.
Read official Help about NCo functions.

Dynamics AX 2012 AIF QueryService through C# - Relations and JoinMode usage between multiple tables

I want to create a complex User defined AIF Query service by using Visual studio and writing code for query service in C#. I am using two custom tables among which one is header and one is line table. I have added fields in the query by using both the tables and applies proper ranges as well and it works fine. Now I want to make a relation between these two tables So I can fetch data based on relation.
Please help me out with how to make a relation between multiple tables in AIF query service.
query.DataSources = new QueryDataSourceMetadata[2];
query.Name = "AXCustomerInfo";
QueryDataSourceMetadata custTableDS = new QueryDataSourceMetadata();
custTableDS.Name = "CustTable";
custTableDS.Table = "CustTable";
custTableDS.Enabled = true;
query.DataSources[0] = custTableDS;
custTableDS.DynamicFieldList = false;
custTableDS.Fields = new QueryDataFieldMetadata[1];
QueryDataFieldMetadata accountNum;
accountNum = new QueryDataFieldMetadata();
accountNum.FieldName = "AccountNum";
accountNum.SelectionField = SelectionField.Database;
custTableDS.Fields[0] = accountNum;
custTableDS.HasRelations = true;
custTableDS.JoinMode =JoinMode.InnerJoin;
QueryDataSourceMetadata dirPartyTableDS = new QueryDataSourceMetadata();
dirPartyTableDS.Name = "DirPartyTable";
dirPartyTableDS.Table = "DirPartyTable";
dirPartyTableDS.Enabled = true;
query.DataSources[1] = dirPartyTableDS;
dirPartyTableDS.DynamicFieldList = false;
dirPartyTableDS.Fields = new QueryDataFieldMetadata[1];
QueryDataFieldMetadata name;
name = new QueryDataFieldMetadata();
name.FieldName = "Name";
name.SelectionField = SelectionField.Database;
dirPartyTableDS.Fields[0] = name;
dirPartyTableDS.HasRelations = false;
result = client.ExecuteQuery(query, ref paging);
foreach (DataRow row in result.Tables[0].Rows)
{
Console.WriteLine(String.Format("{0}", row[0]));
foreach (DataRow row1 in result.Tables[1].Rows)
{
Console.WriteLine(String.Format("{0}", row1[0]));
}
}
See how to add multiple datasources to a query.
Either:
Set the Relations property to Yes on the child data source.
or:
Add a relation by doing the following:
Set the Relations property to No on the child data source.
Right-click the Relations node, and then click New Relation.
Select a field from the parent data source in the Field property.
Select a field from the child data source in the RelatedField property.
Save all modifications.
You can then access the data of the query using OData Query Service.
Also see this question.
Gaurav,
In your code, you are not creating a hierarchical structure of data sources. Hence relations will not work. You will get errors like : You can not add relation to root data source. I already shared my response on AX community. Here is the link:
https://community.dynamics.com/ax/f/33/p/212065/573674#573674
This will work.

Trying to get all entity fields from a CRM record. C#

Straight to the point, I am trying to make an application so that the user can search through their CRM system without going onto CRM. I have managed to retrieve the record but when i try to put the record into a list using the records attributes I am only recieving the Keys.
Here is the code:
EntityCollection retrieved = _service.RetrieveMultiple(query);
foreach (var c in retrieved.Entities)
{
foreach (KeyValuePair<String, Object> attribute in c.Attributes)
{
lstRecordDetails.Items.Add(string.Format(attribute.Key + ": " + attribute.Value));
}
}
This only displays the recordID and the Record Name, I understand these are both the primary keys oh the record and i know i could use c.Attributes["description"] for the description but is there a way that i can get all the fields from the record and display them in the list?
Edit: Details on the query
QueryByAttribute query = new QueryByAttribute(entity);
query.ColumnSet = new ColumnSet(field);
query.Attributes.AddRange(field);
query.Values.AddRange(selected);
The way you can retrieve all the columns of an entity is
query.ColumnSet = new ColumnSet(true);
However, be careful with this, because query all columns has an impact on the system (you should always retrieve explicitly the columns you need).
RetrieveMultipleRequest retrieve = new RetrieveMultipleRequest();
retrieve.Query = query;
retrieve.ReturnDynamicEntities = true;
retrieved = (RetrieveMultipleResponse)Service.Execute(retrieve);
foreach(var dynEntity in retrieved.BusinessEntityCollection)
{
foreach (var prop in dynEntity.Properties)
{
lstRecordDetails.Items.Add(string.Format("{0}:{1}", prop.Name, prop.Value);
}
}

Convert GridView to List<object>

Hi and thanks in advance. I'm having a problem implementing a suggestion that I found here: Convert contents of DataGridView to List in C#
I am grabbing a GridView from a Master page and I need to add a row to the table then rebind it. I am accessing the GridView via a public property on the Master page which is being returned with data. So basically I have done this:
var gsr = master.GridSearchResults;
gsr (gsr != null)
{
var so = new List<MyProperties>();
so = gsr .Rows.OfType<DataGridViewRow>().Select(r => r.Cells.OfType<DataGridViewCell>().Select(c => c.Value).ToArray()).ToList<MyProperties>();
so.Add(new MyProperties()
{
Id = id,
Date = date,
Building = buildingName,
Street = streetName
}
gsr.DataSource = so;
gsr.DataBind();
}
But I'm receiving an error that it cannot convert an instance argument type System.Collections.Generic.IEnumerable<'object[]'> to System.Collections.Generic.IEnumerable<'MyProperties'>. I thought the problem was the call to the array but if I remove it then I just get a variation of the same error.
Turns out my issue was that I shouldn't have been getting the gridview in the first place but getting the the Gridview's source which was in session. So I solved it like this:
var master = (Tab)Master;
master.GridSearchResults.DataSource = null;
var sessions = new Sessions();
sessions.SlideOutSource.Add(new MyProperties {
Id = Id,
StartDate = hidStartDate.Value,
Installation = txtInstall.Text,
Command = txtCommand.Text });
master.GridSearchResults.DataSource = sessions.SlideOutSource;
master.GridSearchResults.DataBind();

Add a second datatable as rowsource of datagridview

I have a datagridview, and I am populating it from a datatable which in turn retrieves it's data from a webservice query (against SalesForce cloud system).
Essentially we want to show the results of attempting to remove attachments from SalesForce cases which have been put on there by the users, currently we query a SalesForce XML webservice called case and we want to add the capability to also query a second new SalesForce object called credit case.
It has been working fine getting its data from an object called cases, and displaying them in a Windows Forms datagridview control.
Now we want to add another object (let's call it creditCases), so I have the query all setup, have added another task object with the fields and datatypes and so on.
Once the dataset is populated we set the data source of the datagridview using gvTaskCases.DataSource = dtCases;
But of course I now have a second datasource (with a different number of columns) that I want to add to the table.
If I do this with my new datatable (gvTaskCases.DataSource = dtcreditCases) how do I stop it replacing the data from the existing datatable?
CODE:
gvTaskCases.DataSource = null;
dtCases.Rows.Clear();
foreach (task_cases item in cases)
{
DataRow drCases = dtCases.NewRow();
// Then add the new row to the collection.
drCases["Case ID"] = item.c_Id;
drCases["Case Number"] = item.c_Number;
drCases["Case Topic"] = item.c_Topic;
drCases["Case SubTopic"] = item.c_Subtopic;
drCases["Account Number"] = item.c_CustomerNumber;
drCases["Additional Info"] = item.c_AdditionalInfo;
drCases["Closed Date"] = Convert.ToDateTime(item.c_ClosedDate).ToString("dd/MM/yyyy");
drCases["Attachment"] = item.c_Attachment;
drCases["Content Type"] = item.c_ContentType;
drCases["Detach Status"] = item.c_Status;
drCases["Document Type"] = item.c_DocumentType;
drCases["Imaging Directory"] = item.c_ImagingDSXDirectory;
drCases["Imaging Document"] = item.c_ImagingDocument;
dtCases.Rows.Add(drCases);
}
gvTaskCases.DataSource = dtCases;
gvTaskCases.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing;
gvTaskCases.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;
foreach (task_creditcases item in creditCases)
{
DataRow drCases = dtCases.NewRow();
// Then add the new row to the collection.
drCases["Case ID"] = item.c_Id;
drCases["Case Number"] = item.c_Name; // SalesForece Credit Case Object CASE NUMBER;
drCases["Account Number"] = item.c_Account__c;
drCases["Closed Date"] = Convert.ToDateTime(item.c_Closed_Date__c).ToString("dd/MM/yyyy");
drCases["Attachment"] = item.c_Imaging_Document_Attached__c;
drCases["Detach Status"] = item.c_Status__c;
drCases["Document Type"] = item.c_Document_Type__c;
drCases["Imaging Directory"] = item.c_Directories__c;
drCases["Imaging Document"] = item.c_Imaging_Document;
dtCases.Rows.Add(drCases);
}
// add the new records:
// Adjust size & hide columns that aren't needed
gvTaskCases.Columns[0].Visible = false;
gvTaskCases.Columns[11].Visible = false;
gvTaskCases.Columns[12].Visible = false;
gvTaskCases.Columns[13].Visible = false;
You can use the Merge method of the DataTable.
((DataTable) gvTaskCases.DataSource).Merge(dtcreditCases);
Another approach is just keep your old DataTable, you have to use a little LINQ to merge the dataTables like this:
gvTaskCases.DataSource = (dtCases.Columns.Count > dtcreditCases.Columns.Count ?
dtCases.AsEnumerable().Concat(dtcreditCases.AsEnumerable()) :
dtcreditCases.AsEnumerable().Concat(dtCases.AsEnumerable())).CopyToDataTable();

Categories

Resources