Hi i have tried to get address1_latitude and address1_longitude from CRM using CRM SDK here is mu code
var querybyattribute11 = new QueryByAttribute("account");
querybyattribute11.ColumnSet = new ColumnSet("name", "address1_city", "statuscode", "address1_postalcode", "address1_latitude", "address1_longitude");
querybyattribute11.Attributes.AddRange("name");
querybyattribute11.Values.AddRange("ASSOCIATED COMBUSTION INC");
EntityCollection entities = service.RetrieveMultiple(querybyattribute11);
foreach (Entity item in entities.Entities)
{
// Console.WriteLine("Name: {0}. Id: {1}", role.Name, role.Id);
list += item.Attributes["name"].ToString() + " " + item.Attributes["address1_longitude"] .ToString() + "\n";
}
But I am not geting it item.Attributes["address1_longitude"]
error message is
'The given key was not present in the dictionary.'
It might be because it's null.
Try either one of these 2 options:
item["address1_longitude"] (shouldn't raise exception, it would return null if blank, otherwise the address longitude)
To check if the column exists:
item.Attributes.ContainsKey("address1_longitude")
Related
Background:
I have ASP.NET Core app. I'm trying to write server-side validation errors to the log.
If ASP.NET Core model validation detects any error in any field in the webform, then ModelState.IsValid is false.
Every field in the webform is listed in ModelState.Values
If a "Value" has one or more errors, then Value.Errors.Count > 0
I want to log a) the webform field name (the Value's "key") and b) each error message for that field.
I'd like to include all this information in a single line (i.e. a single C# "string").
Current code:
// LOG:
// 2022-10-24 09:37:29.0909|Error|ServiceMenu.Q255: The value '' is invalid.
// 2022-10-24 09:37:35.4096|Error|ServiceMenu.Q265: The value '' is invalid.
if (!ModelState.IsValid)
{
foreach (var k in ModelState.Keys)
{
var v = ModelState[k];
if (v.Errors.Count > 0)
{
string s = k + ": ";
for (int i=0; i < v.Errors.Count - 1; i++)
s += v.Errors[i].ErrorMessage + ", ";
s += v.Errors[v.Errors.Count - 1].ErrorMessage;
_logger.LogError(s);
}
}
return Page();
}
Sample output (two required fields, Q255 and 265, were blank):
2022-10-24 09:37:29.0909|Error|ServiceMenu.Q255: The value '' is invalid.
2022-10-24 09:37:35.4096|Error|ServiceMenu.Q265: The value '' is invalid.
Q: Can I simplify this nested loop with LINQ?
Update:
Thank you, everybody.
Evk and T.S. are both absolutely correct: "Don't think that using LINQ is always good." I don't - and their point is very well taken :)
Oliver Weichhold gave me the syntax I was looking for :)
Here's the code I finally wound up with:
// EXAMPLE LOG:
// 2022-10-24 13:24:10.5242|Error|ServiceMenu.Q255: The value '' is invalid.
// 2022-10-24 13:24:24.9692|Error|ServiceMenu.Q265: The value '' is invalid.
if (!ModelState.IsValid)
{
foreach (var k in ModelState.Keys)
{
var v = ModelState[k];
if (v.Errors.Count > 0)
{
string s = string.Join(", ", ModelState[k].Errors
.Select(x => x.ErrorMessage));
_logger.LogError(k + ": " + s);
}
}
...
if (!ModelState.IsValid)
{
var logMessage = string.Join("\n", ModelState.Keys
.Where(x => ModelState[x].Errors?.Count > 0)
.Select(x => $"{x}: " + string.Join(", ", ModelState[x].Errors.Select(y => y.ErrorMessage))));
_logger.LogError(logMessage);
}
I'm having a bit of trouble getting my code to work. I'm retrieving all of my actor objects from my database, which are the castmembers of a certain movie, using LINQ to SQL. I've checked the output and they're just fine.
Because I had to use a dictionary to show the actors names as a whole, I need to compare whether the selected values of the listbox are the same as the combination of the First- and LastName of the actor.
The first thing I'm doing is going through all the selected items in my listbox. Next, I want to compare them to the First and LastName of the actorsm which I retrieved using LINQ. But it doesn't work like I want it to.
Example: Movie is Pulp Fiction and the Actors related to the movie are Uma Thurman, Samuel L. Jackson and John Travolta. When I run this code I get a total of 3 MessageBoxes with the following output:
[4, Uma Thurman] Matches Uma Thurman
[5, Samuel L. Jackson] Matches Uma Thurman
[6, John Travolta] Matches Uma Thurman
Though what I really want to achieve is that it breaks out of the loop after finding Uma and then get a messagebox saying:
[5, Samuel L. Jackson] Matches Samuel L. Jackson. and so forth. I want to do this since I want to delete and/or insert actors that are selected/deselected from the movie.
var deleteMovieActors = db.MovieActors.Where(mid => mid.Movie_MovieId == MovieId).Select(a => a.Actor);
foreach (var item in lstbActors.SelectedItems)
{
foreach (Actor a in deleteMovieActors)
{
if (lstbActors.SelectedItem.ToString().Contains(a.FirstName + " " + a.LastName))
{
MessageBox.Show(item.ToString() + " Matches " + a.FirstName + " " + a.LastName);
break;
}
}
}
Here's how I create my listbox:
private void InitializeListBox()
{
var actors = new Dictionary<int, string>();
foreach (var actor in db.Actors.ToList())
{
actors.Add(actor.ActorId, actor.FirstName + " " + actor.LastName);
}
lstbActors.DataSource = actors.ToList();
lstbActors.ValueMember = "Key";
lstbActors.DisplayMember = "Value";
lstbActors.SelectedIndex = -1;
// Get Actors by MovieId
var MAct = from ma in db.MovieActors
where ma.Movie_MovieId == MovieId
select ma;
List<Actor> act = new List<Actor>();
foreach (var ma in MAct)
{
act.Add(db.Actors.Where(a => a.ActorId == ma.Actor_ActorId).Single());
}
foreach (Actor a in act)
{
int index = lstbActors.FindStringExact(a.FirstName + " " + a.LastName);
if (index != -1)
{
lstbActors.SetSelected(index, true);
}
}
}
The problem is located in the condition of the IF statement. The SelectedItem property returns the first occurence over and over in the loop.
if (lstbActors.SelectedItem.ToString().Contains(a.FirstName + " " + a.LastName))
{
MessageBox.Show(item.ToString() + " Matches " + a.FirstName + " " + a.LastName);
break;
}
When I changed the code as following, it works:
item.ToString().Contains(a.FirstName + " " + a.LastName
If you want exact matches of First and Last Name use string.Equals() rather than contains because contains return all of the string which contains the specified keyword e.g if you use contains for string "Hello" on strings "Hello" and "Hello World", then it will give you both Hello and Hello World.
Hello this is my first post on Stackoverflow.
Background:
I am building a Class to use the WindowsManagementInstrumentation library to query DNS Servers.
Problem:
When I search for a dns record that does not exist on the DNS Server I get the following error:
An exception of type 'System.Management.ManagementException' occurred in System.Management.dll but was not handled in user code
It is caused from this line:
if (search.Get().Count > 0)
In looking at this line I found the exception is on the Count.
I am not sure why this happens. If I search for a DNS Record that I know is on the DNS Server then Count returns the correct number and doesn't throw an error. I expect Count to return 0 if it can't find a DNS Record on the server. I could do a try catch and when it throws the exception handle it on my end so it but I feel this is not the right way to do it. Any ideas?
I get the following error info when I debug.
Count 'Count' threw an exception of type 'System.Management.ManagementException' int {System.Management.ManagementException}
base {"Generic failure "} System.SystemException {System.Management.ManagementException}
base {"Generic failure "} System.Exception {System.Management.ManagementException}
Data {System.Collections.ListDictionaryInternal} System.Collections.IDictionary {System.Collections.ListDictionaryInternal}
HelpLink null string
HResult -2146233087 int
InnerException null System.Exception
Message "Generic failure " string
Source "System.Management" string
StackTrace " at System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode)\r\n at System.Management.ManagementObjectCollection.ManagementObjectEnumerator.MoveNext()\r\n at System.Management.ManagementObjectCollection.get_Count()" string
ErrorCode Failed System.Management.ManagementStatus
Full Method:
public List<ManagementObject> GetRecords(string domain, string name, string type)
{
//Object to hold list of RRecords/DNS Records
List<ManagementObject> rrecords = new List<ManagementObject>();
//Init properites for the given type
Properties propertiesStruct = new Properties(type);
//Query
string query = "SELECT * FROM " + propertiesStruct.Table + " WHERE DomainName = '" + domain.ToLower() + "' AND OwnerName ='" + name.ToLower() + "." + domain.ToLower() + "'";
//Search for results
ManagementObjectSearcher search = new ManagementObjectSearcher(this.scope, new ObjectQuery(query));
//Make sure we have something and if we do loop through them to grab the data
if (search.Get().Count > 0)
{
foreach (ManagementObject results in search.Get())
{
rrecords.Add(results);
}
}
return rrecords;
}
Sorry if I missed anything and thanks for the help.
Just so anyone else who runs across this knows what I ended up doing. I ended up wrapping the count check in a try catch and if it throws an exception I ignore it and just return an empty rrecords object since the search didn't find anything.
Using AMO I can happily confirm the existance of two dimension attributes. I'd like to create a relationship. The following (result) returns a result code of 0 what ever that means however after processing the cube there is no relation. Suggestions?
// confirm db exists
db = objServer.Databases.FindByName(strCubeDBName);
// find the dimension
string dimName = "Product";
Dimension dim = db.Dimensions.FindByName(dimName);
attrSource = dim.Attributes.FindByName("Spanish Product Subcategory Name");
if (attrSource != null)
Console.WriteLine(attrSource + " - source attribute exists");
else
throw new Exception(attrSource + " - source attribute does not exist");
attrRelated = dim.Attributes.FindByName("French Product Subcategory Name");
if (attrRelated != null)
Console.WriteLine(attrRelated + " - Related attribute exists");
else
throw new Exception(attrRelated + " - Related attribute does not exist");
int result;
result = attrSource.AttributeRelationships.Add(new AttributeRelationship(attrRelated));
Console.WriteLine(result);
dim.Process(ProcessType.ProcessUpdate);
After adding the new attribute relationship, you need to call Update on the dimension. In your code above, just before calling Process, add the following line:
dim.Update(UpdateOptions.ExpandFull | UpdateOptions.AlterDependents)
I'm in VS2008 with Entity Framework. I'm accessing objects from the database using esql for WHERE IN functionality. I'm passing a ton of IDs to the select statement so I chunk it up into sets of 800. Then I merge the results together from each chunk. My goal is to obtain results for each chunk in parallel, rather than waiting synchronously. I installed Reactive Framework and am pretty sure I need to make use of ForkJoin. However, I can't figure out how to convert this function to use it. Here's my existing code:
public static IList<TElement> SelectWhereIn<TElement, TValue>(this ObjectContext context, string fieldName, IList<TValue> idList)
{
var chunkedIds = idList.Split(CHUNK_SIZE);
string entitySetName = typeof(TElement).Name + "Set";
var retList = new List<TElement>();
foreach (var idChunk in chunkedIds)
{
string delimChunk = string.Join(",", idChunk.Select(x => x.ToString()).ToArray());
ObjectQuery<TElement> query = context.CreateQuery<TElement>("SELECT VALUE x FROM " + entitySetName + " AS x");
query = query.Where("it." + fieldName + " IN {" + delimChunk + "}");
retList.AddRange(query);
}
return retList;
}
Thanks!
EDIT >>>
I modified the code to use Poor Man's as below:
public static IList<TElement> SelectWhereIn<TElement, TValue>(this ObjectContext context, string fieldName, IList<TValue> idList)
{
var chunkedIds = idList.Split(CHUNK_SIZE);
string entitySetName = typeof(TElement).Name + "Set";
var chunkLists = new List<IEnumerable<TElement>>();
Parallel.ForEach(chunkedIds, idChunk =>
{
string delimChunk = string.Join(",", idChunk.Select(x => x.ToString()).ToArray());
ObjectQuery<TElement> query = context.CreateQuery<TElement>("SELECT VALUE x FROM " + entitySetName + " AS x");
query = query.Where("it." + fieldName + " IN {" + delimChunk + "}");
chunkLists.Add(query.ToList());
});
var retList = new List<TElement>();
foreach (var chunkList in chunkLists)
{
retList.AddRange(chunkList);
}
return retList;
}
It worked great the first time. But the second time I ran it, I got this error:
The connection was not closed. The connection's current state is connecting.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: The connection was not closed. The connection's current state is connecting.
Source Error:
Line 49: foreach (var iAsyncResult in resultList)
Line 50: {
Line 51: del.EndInvoke(iAsyncResult);
Line 52: iAsyncResult.AsyncWaitHandle.Close();
Line 53: }
It's interesting, b/c Emre (the author of the library) has an edit to his original post talking about how he added those lines of code for added safety. Am i using it right? Or was his v1 safer after all?
VS2010 does have that with PLINQ. Using the extensions AsParallel().WithDegreeOfParallelism(nbProcessors) would do what you need.
With VS2008, I've used Poor Man's Parallel.ForEach Iterator by Emre Aydinceren in the past when I was trying to work around a performance bottleneck, try to give it a shot.
EDIT: In reaction to the error you added, it might be a random shot in the dark, but seperate contexts for each thread ? Like so:
Parallel.ForEach(chunkedIds, idChunk =>
{
ObjectContext context = new MyContext(connStr);//depending what's your config
// like, with or w/o conn string
string delimChunk = string.Join(",", idChunk.Select(x => x.ToString()).ToArray());
ObjectQuery<TElement> query = context.CreateQuery<TElement>("SELECT VALUE x FROM " + entitySetName + " AS x");
query = query.Where("it." + fieldName + " IN {" + delimChunk + "}");
chunkLists.Add(query.ToList());
});
You might have to tweak around some things (like take the connextion string from the Context extended to instantiate new Contexts).