Here is the fetchXML:
<fetch version='1.0' mapping='logical' distinct='true'>
<entity name='listmember'>
<link-entity name='contact' from='contactid' to='entityid' alias='c'>
<attribute name='contactid' />
<attribute name='telephone1' />
<link-entity name='phonecall' from='ic_customer' to='contactid' alias='pc' link-type='outer'>
<attribute name='activityid' />
<attribute name='ic_end' />
<filter type='and'>
<filter type='or'>
<condition attribute='statuscode' operator='eq' value='1' />
</filter>
</filter>
</link-entity>
<filter type='and'>
<condition attribute='statecode' operator='eq' value='0' />
<condition attribute='telephone1' operator='not-null' />
<condition attribute='donotphone' operator='eq' value='0' />
</filter>
</link-entity>
<filter type='and'>
<condition attribute='listid' operator='in'><value>{ed0fa81c-1b65-e611-80ee-5065f38be311}</value></condition>
<condition entityname='pc' attribute='activityid' operator='null' />
</filter>
</entity>
</fetch>
Now I want to access the ic_end attribute when I got object through RetrieveMultiple method in C#.
I tried to get attribute via:
var endDate = (DateTime)((AliasedValue)contact["c.pc.ic_end"]).Value;
I got an error that no attribute with that name was found.
Any suggestions?
Few things here:
First and foremost the way you retrieve the linked-entity attribute is incorrect, the attributes are returned in a format of alias.attributename (pc.ic_end in this case).
Also always check if the attribute exists based on your join criteria it may not always be returned. Retrieve attribute logic should be along the lines of:
if (contact.Attributes.Contains("pc.ic_end") &&
contact.Attributes["pc.ic_end"] != null)
{
var endDate = (DateTime) ((AliasedValue) contact["pc.ic_end"]).Value;
}
link-entity name='phonecall' from='ic_customer' to='contactid'
alias='pc' link-type='outer'
I got an error that no attribute with that name was found.
As soon as you have the link-type specified as outer, all contacts With OR Without phone call records are returned. So this is an intended behaviour, you would need to check if the attribute exists in the attribute list returned.
If you want the query to only ever return a contact record With a phone call, use a natural inner join
<link-entity name='phonecall' from='ic_customer' to='contactid' alias='pc'>
Related
I have the following FetchXML:
<fetch>
<entity name="list" >
<attribute name="listname" />
<attribute name="listid" alias="List" />
<filter type="and" >
<condition attribute="listname" operator="eq" value="Test 1" />
</filter>
<link-entity name="listmember" from="listid" to="listid" intersect="true" alias="listmember" >
<attribute name="entitytype" />
<attribute name="listmemberid" />
<attribute name="entityid" />
<link-entity name="contact" from="contactid" to="entityid" alias="contact" >
<attribute name="contactid" />
<attribute name="owneridname" />
<attribute name="owneridtype" />
<attribute name="ownerid" />
</link-entity>
</link-entity>
</entity>
The result looks like this:
<resultset morerecords="0" paging-cookie="<cookie page="1"><listid lastnull="1" firstnull="1" /></cookie>">
<result>
<listname>Test 1</listname>
<listmember.entitytype formattedvalue="2">2</listmember.entitytype>
<listmember.listmemberid>{6739D9B9-xxxx-xxxx-xxxx-000D3A3852A3}</listmember.listmemberid>
<listmember.entityid type="2">{039FD4C6-xxxx-xxxx-xxxx-000D3A385A1C}</listmember.entityid>
<contact.contactid>{039FD4C6-xxxx-xxxx-xxxx-000D3A385A1C}</contact.contactid>
<contact.ownerid name="CRM Test" dsc="" type="8" yomi="CRM Test">{5ABA5CBA-xxxx-xxxx-xxxx-D472F64781F6}</contact.ownerid>
</result>
</resultset>
My issue now is that I have a generic way to retrieve the attributes returned by a FetchXml. But since this one has linked entites the aliases are added to the result, like:
<listmember.listmemberid>
So my retrieve will throw an error since I am looking for "listmemberid"
Is there a way to avoid having these aliases added to the result? Specially since the attribute names are unique?
Any ideas to get around this issue?
The only option to override the alias of the select column which is working - when you do aggregate function and I tested the below working example.
<fetch top="50" aggregate="true" >
<entity name="account" >
<attribute name="businesstypecode" alias="test" groupby="true" />
<link-entity name="contact" from="accountid" to="accountid" link-type="inner" alias="acc" >
<attribute name="accountrolecode" alias="testing" groupby="true" />
</link-entity>
</entity>
</fetch>
Result:
test testing
1 3
1
This didn't work. I don't know why, maybe limitation of fetchxml.
<fetch top="50" >
<entity name="contact" >
<attribute name="fullname" />
<link-entity name="account" from="accountid" to="accountid" alias="acct" >
<attribute name="name" alias="acctNAME" />
</link-entity>
</entity>
</fetch>
Result:
fullname acct.name
arun account arun account
Even with the Query Expression, you will get a special datatype called AliasedValue to handle this, so this is intended behavior. Read more
You get these aliases and then it’s value because you are retrieving data from linked entity. Whenever you do that I.e retrieving from linked entity you will have to use aliases, as far as I know you cannot circumvent it.
What I could suggest is if you need data only from ListMember entity and not from List and contact,
Create your fetch based on list member entity such as
select * from listmember where listname="Test 1"
But as soon as you need data from related entity, that related entity shall be aliased.
When maxSizeRollBackups is decreased (suppose 4 to 2), it is expected that, only 2 files should be kept and extra files should be deleted, but it is not happening.
However, In case I increase the maxSizeRollBackups value, it is working according to the count.
Log4Net setting:
<?xml version="1.0"?>
<configuration>
<log4net>
<logger name="ConsoleLog">
<level value="FATAL" />
<level value="ERROR" />
<level value="WARN" />
<level value="INFO" />
<level value="DEBUG" />
<appender-ref ref="ConsoleLogFile" />
</logger>
<appender name="ConsoleLogFile" type="log4net.Appender.RollingFileAppender">
<file type="log4net.Util.PatternString" value="%property{ConsoleSetup}" />
<appendToFile value="true" />
<maxSizeRollBackups value="4" />
<maximumFileSize value="1KB" />
<rollingStyle value="Composite" />
<datePattern value="yyyyMMdd" />
<staticLogFileName value="true" />
<Encoding value="UTF-8" />
<layout type="log4net.Layout.PatternLayout">
<!-- %d:DateTime, %t:Thread, %-5p:Categories, %c:LoggerName, %m:ADKMessage, %n:line sepalator-->
<param name="ConversionPattern" value="%d ,%-5p, %m%n" />
</layout>
</appender>
Watcher in C# on the log config:
log4net.Config.XmlConfigurator.ConfigureAndWatch(new System.IO.FileInfo(sPath));
According to maxSizeRollBackups setting (4) above, below files are existing.
"Application_ConsoleSetup.log"
"Application_ConsoleSetup.log.1"
"Application_ConsoleSetup.log.2"
"Application_ConsoleSetup.log.3"
"Application_ConsoleSetup.log.4"
Then I set, maxSizeRollBackups to 2 then I think, below files should be deleted, but not getting deleted. I want to find out cause of this issue
"Application_ConsoleSetup.log.3"
"Application_ConsoleSetup.log.4"
Note, If I set, maxSizeRollBackups to 6 then files below are getting generated as expected.
"Application_ConsoleSetup.log.5"
"Application_ConsoleSetup.log.6"
the reason is that Log4net doesn't do a full inventory of its log files and deletes those that shouldn't be there according to the current configuration. It just observes the configuration settings while it is logging. Looking at the method RollOverRenameFiles in RollingFileAppender.cs, you can see that if a log file rollover happens, the oldest file is being deleted and the other files are renamed. "Oldest file" refers to the oldest file according to the current configuration. If your configuration states that there should only be 2 backups, the oldest file is <baseFilename>.2. Log4net never checks if there are other files (.3, .4 and so on) that were created earlier due to a different configuration.
i want to replace some symbols in fetchxml query
Fetchxml.Replace("\"", "'").Replace("\n", "\"+").Replace("<", "\"<");
I want to replace \n (return to the line) with "+
and replace the < with "<
But
the Replace("\n", "\"+") that doesn't work it still \n
and the Replace("<", "\"<") it replace the < with \"< istead of "<
Sample XML:
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="false"> <entity name="account"> <attribute name="name" /> <filter type="and"> <condition attribute="statecode" operator="eq" value="0" /> </filter> <link-entity name="contact" from="contactid" to="primarycontactid" visible="false" link-type="outer" alias="accountprimarycontactidcontactcontactid"> <attribute name="emailaddress1" /> </link-entity> </entity> </fetch>
Desired output:
<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>"+ "<entity name='account'>"+ "<filter type='and'>"+ "<condition attribute='statecode' operator='eq' value='0' />"+ "</filter>"+ "</entity>"+ "</fetch>
It looks what you're trying to do is simply insert '+' into the text elements of this XML. This is a bit of an odd thing to be doing, but I'll bite.
I would suggest this is easy in Perl, using XML::Twig. The problem with XML is it doesn't parse easily with regex, but it does parse easily with an XML parser.
So given input XML of:
<fetch distinct="false" mapping="logical" output-format="xml-platform" version="1.0">
<entity name="account">
<attribute name="name"/>
<filter type="and">
<condition attribute="statecode" operator="eq" value="0"/>
</filter>
<link-entity alias="accountprimarycontactidcontactcontactid" from="contactid" link-type="outer" name="contact" to="primarycontactid" visible="false">
<attribute name="emailaddress1"/>
</link-entity>
</entity>
</fetch>
It can be turned into a close approximation of your desired output XML:
#!/usr/bin/perl
use strict;
use warnings;
my $xml = XML::Twig->new(
'pretty_print' => 'indented',
'twig_handlers' => {
'attribute' => sub { $_->delete },
'link-entity' => sub { $_->delete },
},
);
$xml->parse( \*DATA );
$xml ->print;
This gives you:
<fetch distinct="false" mapping="logical" output-format="xml-platform" version="1.0">
<entity name="account">
<filter type="and">
<condition attribute="statecode" operator="eq" value="0"/>
</filter>
</entity>
</fetch>
(If you don't want it line separated and indented, turn off that pretty_print flag)
Now, I'm not entirely sure what you're trying to accomplish with the + symbols there. Are you perhaps trying to quote your XML result? In all honesty, that doesn't really make an awful lot of sense from an XML perspective.
If you really had to though, I guess you could:
my $output_xml = $xml ->sprint;
$output_xml =~ s/^\s+//gm;
$output_xml =~ s/\n</"+ "</g;
print $output_xml;
Which would give you:
<fetch distinct="false" mapping="logical" output-format="xml-platform" version="1.0">"+ "<entity name="account">"+ "<filter type="and">"+ "<condition attribute="statecode" operator="eq" value="0"/>"+ "</filter>"+ "</entity>"+ "</fetch>
And is that even possible?
I have the fetch xml already to filter list B out of list A by record id however I also want the option to filter it by the email address.
For example:
List A has 2 records. Record 1: Bob#BobMail.com and Record 2: Susy#SusyMail.com.
List B has 1 record. Record 3 Bob#BobMail.com which is a different contact than Record 1 but has the same email address.
Still with me? Sorry for the confusing explanation...
The query should take List A, do an outer join with List B to produce the result which only contains Record 2 with the email address Susy#SusyMail.com.
If there's any way I can be more clear on what I'm trying to do don't hesitate to ask.
After a night to think about it and a fresh pair of eyes in the morning I realized I simply needed to link the listmember to the contact exactly as I had been with the by ID option and then add an additional link to the contact entity on the email address.
<fetch mapping="logical" version="1.0" page="1" count="100" >
<entity name="contact" >
<link-entity name="listmember" from="entityid" to="contactid" >
<filter>
<condition attribute="listid" operator="eq" value="06197bff-a299-e311-aae4-6c3be5a892e8" />
</filter>
</link-entity>
<attribute name="contactid" />
<attribute name="emailaddress1" />
<filter type="and" >
<condition attribute="emailaddress1" operator="not-null" />
<condition attribute="donotbulkemail" operator="ne" value="1" />
</filter>
<link-entity name="listmember" from="entityid" to="contactid" link-type="outer" alias="exclusionlist" >
<attribute name="entityid" />
<filter type="and" >
<condition attribute="listid" operator="eq" value="06197bff-a299-e311-aae4-6c3be5a892e8" />
</filter>
</link-entity>
<link-entity name="contact" from="emailaddress1" to="emailaddress1" link-type="outer" alias="emailaddress" >
<attribute name="fullname" />
<attribute name="emailaddress1" />
</link-entity>
<order descending="false" attribute="emailaddress1" />
</entity>
And then we filter out the reults by the alias:'
results = results.Where(x => !x.Contains("exclusionlist.entityid") || !x.Contains("emailaddress.emailaddress1")).ToList();
Hopefully this helps someone else though I do feel a bit dumb for asking now...
I'm trying to use FetchXML to pull in a list of courses with an 'entry year' related entity. What I would like to do is only return a single record for each course (could return multiple courses) with the latest year (e.g I would want it to pick the last year out of 2012, 2013, 2014 - so in this case 2014). So I currently have:
<fetch mapping="logical" distinct="true">
<entity name="course">
<all-attributes/>
<order attribute="name" />
<link-entity name="course_entryyear" from="courseid" to="courseid">
<link-entity name="entryyear" from="entryyearid" to="entryyearid">
<attribute name="year" />
</link-entity>
</link-entity>
</entity>
</fetch>
Is this possible to do within FetchXML and if so how can I amend the above?
Cheers
What about adding count="1" and inner join to the linked entities along with some ordering:
So it would look like:
<fetch mapping="logical" distinct="true">
<entity name="course">
<all-attributes/>
<order attribute="name" />
<link-entity name="course_entryyear" from="courseid" to="courseid" link-type="inner">
<link-entity name="entryyear" from="entryyearid" to="entryyearid" link-type="inner" count="1">
<attribute name="year" />
<order attribute="year" descending="true"/>
</link-entity>
</link-entity>
</entity>
</fetch>
Depending on how you are displaying the course list you might want to change the link-type for the "course-entryyear" from inner to outer, so that all courses get displayed even if they haven't been served yet.