Unexpected double WHERE clause in Servicestack OrmLite - servicestack

We have an issue that occurs at every method call for limited periods of time. Then it works as expected. The issue is that the code produces double WHERE clauses.
We're using Servicestack 4.5.14
The method we have:
protected static void InsertOrUpdate<T>(
IDbConnection connection,
T item,
Expression<Func<T, bool>> singleItemPredicate,
Expression<Func<T, object>> updateOnlyFields = null)
{
var type = item.GetType();
var idProperty = type.GetProperty("Id");
if (idProperty == null)
{
throw new Exception("Cannot insert or update on a class with no ID property");
}
var currentId = (int)idProperty.GetValue(item);
if (currentId != 0)
{
throw new Exception("Cannot insert or update with non-zero ID");
}
var query = connection.From<T>().Where(singleItemPredicate).WithSqlFilter(WithUpdateLock);
T existingItem;
try
{
existingItem = connection.Select(query).SingleOrDefault();
Log.Verbose(connection.GetLastSql);
}
catch (SqlException)
{
Log.Verbose(connection.GetLastSql);
throw;
}
if (existingItem == null)
{
Insert(connection, item);
return;
}
var existingId = (int)idProperty.GetValue(existingItem);
idProperty.SetValue(item, existingId);
try
{
var affectedRowCount = connection.UpdateOnly(item, onlyFields: updateOnlyFields, where: singleItemPredicate);
Log.Verbose(connection.GetLastSql);
if (affectedRowCount != 1)
{
throw new SwToolsException("Update failed");
}
}
catch (SqlException)
{
Log.Verbose(connection.GetLastSql);
throw;
}
}
When it all works, an example output from the logs could be:
SELECT "Id", "Application", "Hostname", "LastContact", "Version", "ToolState", "ServerState"
FROM "ca"."ExecutionHost"
WITH (UPDLOCK) WHERE ("Hostname" = #0)
UPDATE "ca"."ExecutionHost" SET "LastContact"=#LastContact, "Version"=#Version, "ToolState"=#ToolState, "ServerState"=#ServerState WHERE ("Hostname" = #0)
When it fails, the output (same session, only seconds later) was:
SELECT "Id", "Application", "Hostname", "LastContact", "Version", "ToolState", "ServerState"
FROM "ca"."ExecutionHost"
WITH (UPDLOCK) WHERE ("Hostname" = #0)
UPDATE "ca"."ExecutionHost" SET "LastContact"=#LastContact, "Version"=#Version, "ToolState"=#ToolState, "ServerState"=#ServerState WHERE "LastContact"=#LastContact, "Version"=#Version, "ToolState"=#ToolState, "ServerState"=#ServerState WHERE ("Hostname" = #0)
Marked in bold is the addition to the SQL that makes the call to fail. It seems that it adds an additional WHERE clause with the content from the SET clause.
We've been debugging this for a while and don't really know if the issue is on "our" side or in Servicestack.
Any ideas on where to continue?

Related

Microsoft.Azure.CognitiveServices.Search.EntitySearch.EntitySearchClient.Entities.Search(location: <latitude>:? <longitude>:?

I'm running the Microsoft sample for Bing Entity Search using the SDK and (NOT the REST API.) I can.t figure out how to enter the location key/value pair, based on this documentation:
https://learn.microsoft.com/en-us/dotnet/api/microsoft.azure.cognitiveservices.search.entitysearch.entitiesoperationsextensions.search?f1url=https%3A%2F%2Fmsdn.microsoft.com%2Fquery%2Fdev15.query%3FappId%3DDev15IDEF1%26l%3DEN-US%26k%3Dk(Microsoft.Azure.CognitiveServices.Search.EntitySearch.EntitiesOperationsExtensions.Search);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.7.2);k(DevLang-csharp)%26rd%3Dtrue&view=azure-dotnet
I would like to continue to use named parameters so I can still do this:
var restaurants = client.Entities.Search(query: currentQuery, location: lat:? long:?);
The method with the query and location from the Microsoft sample will look like this:
public static void MultipleCurrentQueryLookup(string subscriptionKey)
{
var client = new EntitySearchClient(new ApiKeyServiceClientCredentials subscriptionKey));
try
{
string currentQuery = Settings1.Default.CurrentQuery;
var restaurants = client.Entities.Search(query: currentQuery,
location: "lat:47.623, long:-122.361, re:380m");
if (restaurants?.Places?.Value?.Count > 0)
{
// get all the list items that relate to this query
var listItems = restaurants.Places.Value.Where(thing => thing.EntityPresentationInfo.EntityScenario == EntityScenario.ListItem).ToList();
if (listItems?.Count > 0)
{
var sb = new StringBuilder();
foreach (var item in listItems)
{
var place = item as Place;
if (place == null)
{
Console.WriteLine("Unexpectedly found something that isn't a place named \"{0}\"", item.Name);
continue;
}
sb.AppendFormat(",{0} ({1}) {2}", place.Name, place.Telephone, place.Url);
}
Console.WriteLine("Ok, we found these places: ");
Console.WriteLine(sb.ToString().Substring(1));
}
else
{
Console.WriteLine("Couldn't find any relevant results for \"The Current Query\"");
}
}
else
{
Console.WriteLine("Didn't see any data..");
}
}
catch (ErrorResponseException ex)
{
Console.WriteLine("Encountered exception. " + ex.Message);
}
}

lotus.domino.local.Item cannot be cast to lotus.domino.RichTextItem

I try to put a file into a richtext but it crashes !
In my first code, I try to use directly "getFirstItem", in first time it was ok but now i try to use it again and it crashed.
In second time i pass with an object and it find my obj doesn't an richtextItem (instanceof) ???
I don't understand.
I have the message : "lotus.domino.local.Item cannot be cast to lotus.domino.RichTextItem" ?
Could you help me ?
public void copieFichierDansRichText(String idDocument, String nomRti, File file,
String nameFichier, String chemin) throws NotesException {
lotus.domino.Session session = Utils.getSession();
lotus.domino.Database db = session.getCurrentDatabase();
lotus.domino.Document monDoc = db.getDocumentByUNID(idDocument);
lotus.domino.RichTextItem rtiNew = null;
try {
try {
if (monDoc != null) {
// if (monDoc.getFirstItem(nomRti) != null) {
// rtiNew = (lotus.domino.RichTextItem)
// monDoc.getFirstItem(nomRti);
// } else {
// rtiNew = (lotus.domino.RichTextItem)
// monDoc.createRichTextItem(nomRti);
// }
Object obj = null;
if (monDoc.getFirstItem(nomRti) != null) {
obj = monDoc.getFirstItem(nomRti);
if (obj instanceof lotus.domino.RichTextItem) {
rtiNew = (lotus.domino.RichTextItem) obj;
}
} else {
obj = monDoc.createRichTextItem(nomRti);
if (obj instanceof lotus.domino.RichTextItem) {
rtiNew = (lotus.domino.RichTextItem) obj;
}
}
PieceJointe pieceJointe = new PieceJointe();
pieceJointe = buildPieceJointe(file, nameFichier, chemin);
rtiNew.embedObject(EmbeddedObject.EMBED_ATTACHMENT, "", pieceJointe.getChemin()
+ pieceJointe.getNomPiece(), pieceJointe.getNomPiece());
monDoc.computeWithForm(true, false);
monDoc.save(true);
}
} finally {
rtiNew.recycle();
monDoc.recycle();
db.recycle();
session.recycle();
}
} catch (Exception e) {
e.printStackTrace();
}
}
EDIT : I try to modify my code with yours advices but the items never considerate as richtextitem. It is my problem. I don't understand why, because in my field it is a richtext ! For it, the item can't do :
rtiNew = (lotus.domino.RichTextItem) item1;
because item1 not be a richtext !!!
I was trying to take all the fields and pass in the item one by one, and it never go to the obj instance of lotus.domini.RichTextItem....
Vector items = doc.getItems();
for (int i=0; i<items.size(); i++) {
// get next element from the Vector (returns java.lang.Object)
Object obj = items.elementAt(i);
// is the item a RichTextItem?
if (obj instanceof RichTextItem) {
// yes it is - cast it as such // it never go here !!
rt = (RichTextItem)obj;
} else {
// nope - cast it as an Item
item = (Item)obj;
}
}
A couple of things. First of all I would set up a util class method to handle the object recycling in a neater way:
public enum DominoUtil {
;
public static void recycle(Base... bases) {
for (Base base : bases) {
if (base != null) {
try {
base.recycle();
} catch (Exception e) {
// Do nothing
}
}
}
}
}
Secondly I would remove the reduntants try/catch blocks and simplify it like this:
private void copieFichierDansRichText(String idDocument, String nomRti, File file,
String nameFichier, String chemin) {
Session session = DominoUtils.getCurrentSession();
Database db = session.getCurrentDatabase();
Document monDoc = null;
try {
monDoc = db.getDocumentByUNID(idDocument);
Item item = monDoc.getFirstItem(nomRti);
if (item == null) {
item = monDoc.createRichTextItem(nomRti);
} else if (item.getType() != Item.RICHTEXT) {
// The item is not a rich text item
// What are you going to do now?
}
RichTextItem rtItem = (RichTextItem) item;
PieceJointe pieceJointe = new PieceJointe();
pieceJointe = buildPieceJointe(file, nameFichier, chemin);
rtItem.embedObject(EmbeddedObject.EMBED_ATTACHMENT, "", pieceJointe.getChemin()
+ pieceJointe.getNomPiece(), pieceJointe.getNomPiece());
monDoc.computeWithForm(true, false);
monDoc.save(true);
} catch (NotesException e) {
throw new FacesException(e);
} finally {
DominoUtil.recycle(monDoc);
}
}
Finally, apart from the monDoc, you need not recycle anything else. Actually Session would be automatically recycled and anything beneath with it (so no need to recycle db, let alone the session!, good rule is don't recycle what you didn't instantiate), but it's not bad to keep the habit of keeping an eye on what you instantiate. If it were a loop with many documents you definitively want to do that. If you also worked with many items you would want to recycle them as early as possible. Anyway, considered the scope of the code it's sufficient like this. Obviously you would call DominoUtil.recycle directly from the try block. If you have multiple objects you can recycle them at once possibly by listing them in the reverse order you set them (eg. DominoUtil.recycle(item, doc, view)).
Also, what I think you miss is the check on the item in case it's not a RichTextItem - and therefore can't be cast. I put a comment where I think you should decide what to do before proceeding. If you let it like that and let the code proceed you will have the code throw an error. Always better to catch the lower level exception and re-throw a higher one (you don't want the end user to know more than it is necessary to know). In this case I went for the simplest thing: wrapped NotesException in a FacesException.

CRM 2011 development: Get the following error if I try to get related entity: Object reference not set to an instance of an object

I try to get a related entity and get this error: Object reference not set to an instance of an object.
See below my code:
public IEnumerable<RUBAnnotation> GetAnnotationsByServiceRequestId(string serviceRequestId)
{
List<Annotation> annotationList = new List<Annotation>();
try
{
using (OrganizationServiceProxy organizationProxy = new OrganizationServiceProxy(organisationWebServiceUri, null, userCredentials, deviceCredentials))
{
organizationProxy.EnableProxyTypes();
var service = (IOrganizationService)organizationProxy;
OrganizationServiceContext orgContext = new OrganizationServiceContext(service);
Relationship rel = new Relationship("Incident_Annotation");
// get all incidents by incidentId
IEnumerable<Incident> incidents = from c in orgContext.CreateQuery<Incident>()
where c.Id == new Guid(serviceRequestId)
select c;
return GetAnnotationsEntities(incidents);
}
}
catch (Exception)
{
throw;
}
return null;
}
private List<RUBAnnotation> GetAnnotationsEntities(IEnumerable<Incident> incidents)
{
List<RUBAnnotation> annotationsList = new List<RUBAnnotation>();
try
{
foreach (Incident incident in incidents)
{
foreach (var annotation in incident.Incident_Annotation) // HERE OCCURS THE EXCEPTION!!
{
if (!string.IsNullOrEmpty(annotation.NoteText))
{
var customAnnotation = new RUBAnnotation();
customAnnotation.Id = annotation.Id.ToString();
if (annotation.Incident_Annotation != null)
{
customAnnotation.ServiceRequestId = annotation.Incident_Annotation.Id.ToString();
}
customAnnotation.Message = annotation.NoteText;
customAnnotation.CreatedOn = (DateTime)annotation.CreatedOn;
customAnnotation.UserId = annotation.CreatedBy.Id.ToString();
annotationsList.Add(customAnnotation);
}
}
}
}
catch (Exception e)
{
throw e;
}
return annotationsList;
}
Why do I get this error when I try to get incident.Incident_Annotation ? I think incident.Incident_Annotation is NULL, but why? Al my incidents have minimal 1 or more annotations.
Related entities must be explicitly loaded, you can find more information on this MSDN article:
MSDN - Access Entity Relationships

Plugin code to update another entity when case is created mscrm 2011

Im new with plugin. my problem is, When the case is created, i need to update the case id into ledger. What connect this two is the leadid. in my case i rename lead as outbound call.
this is my code. I dont know whether it is correct or not. Hope you guys can help me with this because it gives me error. I manage to register it. no problem to build and register but when the case is created, it gives me error.
using System;
using System.IO;
using System.ServiceModel;
using System.ServiceModel.Description;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Client;
using System.Net;
using System.Web.Services;
/*
* Purpose: 1) To update case number into lejar
*
* Triggered upon CREATE message by record in Case form.
*/
namespace UpdateLejar
{
public class UpdateLejar : IPlugin
{
/*public void printLogFile(String exMessage, String eventMessage, String pluginFile)
{
DateTime date = DateTime.Today;
String fileName = date.ToString("yyyyMdd");
String timestamp = DateTime.Now.ToString();
string path = #"C:\CRM Integration\PLUGIN\UpdateLejar\Log\" + fileName;
//open if file exist, check file..
if (File.Exists(path))
{
//if exist, append
using (StreamWriter sw = File.AppendText(path))
{
sw.Write(timestamp + " ");
sw.WriteLine(pluginFile + eventMessage + " event: " + exMessage);
sw.WriteLine();
}
}
else
{
//if no exist, create new file
using (StreamWriter sw = File.CreateText(path))
{
sw.Write(timestamp + " ");
sw.WriteLine(pluginFile + eventMessage + " event: " + exMessage);
sw.WriteLine();
}
}
}*/
public void Execute(IServiceProvider serviceProvider)
{
ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
//for update and create event
if (context.InputParameters.Contains("Target") &&
context.InputParameters["Target"] is Entity)
{
// Obtain the target entity from the input parmameters.
Entity targetEntity = (Entity)context.InputParameters["Target"];
// Verify that the entity represents a connection.
if (targetEntity.LogicalName != "incident")
{
return;
}
else
{
try
{
//triggered upon create message
if (context.MessageName == "Create")
{
Guid recordid = new Guid(context.OutputParameters["incidentid"].ToString());
EntityReference app_inc_id = new EntityReference();
app_inc_id = targetEntity.GetAttributeValue<EntityReference>("new_outboundcalllid");
Entity member = service.Retrieve("new_lejer", ((EntityReference)targetEntity["new_outboundcallid"]).Id, new ColumnSet(true));
//DateTime createdon = targetEntity.GetAttributeValue<DateTime>("createdon");
if (app_inc_id != null)
{
if (targetEntity.Attributes.Contains("new_outboundcallid") == member.Attributes.Contains("new_outboundcalllistid_lejer"))
{
member["new_ringkasanlejarid"] = targetEntity.Attributes["incidentid"].ToString();
service.Update(member);
}
}
}
tracingService.Trace("Lejar updated.");
}
catch (FaultException<OrganizationServiceFault> ex)
{
//printLogFile(ex.Message, context.MessageName, "UpdateLejar plug-in. ");
throw new InvalidPluginExecutionException("An error occurred in UpdateLejar plug-in.", ex);
}
catch (Exception ex)
{
//printLogFile(ex.Message, context.MessageName, "UpdateLejar plug-in. ");
tracingService.Trace("UpdateLejar: {0}", ex.ToString());
throw;
}
}
}
}
}
}
Please check,
is that entity containing the attributes or not.
check it and try:
if (targetEntity.Contains("new_outboundcallid"))
((EntityReference)targetEntity["new_outboundcallid"]).Id
member["new_ringkasanlejarid"] = targetEntity.Attributes["incidentid"].ToString();
What is new_ringkasanlejarid's type? You're setting a string to it. If new_ringkasanlejarid is an entity reference, this might be causing problems.
You might want to share the error details or trace log, all we can do is assume what the problem is at the moment.

Non-unique ldap attribute name with Unboundit LDAP SDK

I am attempting to retrieve objects having several attributes with the name from netscape LDAP directory with LDAP SDK from Unboundit. The problem is that only one of the attributes are returned - I am guessing LDAP SDK relays heavily on unique attribute names, is there a way to configure it to also return non-distinct attributes as well?
#Test
public void testRetrievingUsingListener() throws LDAPException {
long currentTimeMillis = System.currentTimeMillis();
LDAPConnection connection = new LDAPConnection("xxx.xxx.xxx", 389,
"uid=xxx-websrv,ou=xxxx,dc=xxx,dc=no",
"xxxx");
SearchRequest searchRequest = new SearchRequest(
"ou=xxx,ou=xx,dc=xx,dc=xx",
SearchScope.SUB, "(uid=xxx)", SearchRequest.ALL_USER_ATTRIBUTES );
LDAPEntrySource entrySource = new LDAPEntrySource(connection,
searchRequest, true);
try {
while (true) {
try {
System.out.println("*******************************************");
Entry entry = entrySource.nextEntry();
if (entry == null) {
// There are no more entries to be read.
break;
} else {
Collection<Attribute> attributes = entry.getAttributes();
for (Attribute attr : attributes)
{
System.out.println (attr.getName() + " " + attr.getValue());
}
}
} catch (SearchResultReferenceEntrySourceException e) {
// The directory server returned a search result reference.
SearchResultReference searchReference = e
.getSearchReference();
} catch (EntrySourceException e) {
// Some kind of problem was encountered (e.g., the
// connection is no
// longer valid). See if we can continue reading entries.
if (!e.mayContinueReading()) {
break;
}
}
}
} finally {
entrySource.close();
}
System.out.println("Finished in " + (System.currentTimeMillis() - currentTimeMillis));
}
Non-unique LDAP attributes are considered multivalued and are reperesented as String array.
Use Attribute.getValues() instead of attribute.getValue.

Resources