LoadBy method returns null if provided parameter is 0 - codefluent

My model contains an entity with a numeric property:
<cf:entity name="Land">
<cf:property name="Id" key="true" />
<cf:property name="Landcode" typeName="ushort" nullable="false" usePersistenceDefaultValue="false" />
<cf:method name="LoadByLandcode"
body="LOADONE(ushort landCode) WHERE Landcode = #landcode">
</cf:method>
</cf:entity>
The generated code for the LoadByLandcode method looks like this:
public static Land LoadByLandcode(ushort landCode)
{
if ((landCode == CodeFluentPersistence.DefaultUInt16Value))
{
return null;
}
Land land = new Land();
CodeFluent.Runtime.CodeFluentPersistence persistence = CodeFluentContext.Get(BusinessLayerStoreName).Persistence;
persistence.CreateStoredProcedureCommand(null, "Land", "LoadByLandcode");
persistence.AddParameter("#landCode", landCode);
System.Data.IDataReader reader = null;
try
{
reader = persistence.ExecuteReader();
if ((reader.Read() == true))
{
land.ReadRecord(reader, CodeFluent.Runtime.CodeFluentReloadOptions.Default);
land.EntityState = CodeFluent.Runtime.CodeFluentEntityState.Unchanged;
return land;
}
}
finally
{
if ((reader != null))
{
reader.Dispose();
}
persistence.CompleteCommand();
}
return null;
}
Why does CodeFluent return null if the provided landCode parameter is 0?
I do not want this to happen, because landCode 0 is also a valid value in the database.
How can I change this behaviour?

The parameter of the method uses the persistence default value (0 by default). So to avoid the default value check, you have to indicate the parameter is nullable:
<cf:method name="LoadByLandcode"
body="LOADONE(Landcode?) WHERE Landcode = #Landcode">
</cf:method>
public static Land LoadByLandcode(ushort landcode)
{
Land land = new Land();
CodeFluent.Runtime.CodeFluentPersistence persistence = CodeFluentContext.Get(Constants.StoreName).Persistence;
persistence.CreateStoredProcedureCommand(null, "Land", "LoadByLandcode");
persistence.AddRawParameter("#Landcode", landcode);
System.Data.IDataReader reader = null;
try
{
reader = persistence.ExecuteReader();
if ((reader.Read() == true))
{
land.ReadRecord(reader, CodeFluent.Runtime.CodeFluentReloadOptions.Default);
land.EntityState = CodeFluent.Runtime.CodeFluentEntityState.Unchanged;
return land;
}
}
finally
{
if ((reader != null))
{
reader.Dispose();
}
persistence.CompleteCommand();
}
return null;
}

Related

CodeFluent produces either a check for 0 in the method or a check for NULL in the stored procedure

My model contains an entity with a numeric Landcode property. The value 0 is a valid value for this property:
<cf:entity name="Land">
<cf:property name="Id" key="true" />
<cf:property name="Landcode" typeName="ushort" nullable="false" usePersistenceDefaultValue="false" />
<cf:method name="LoadByLandcode"
body="LOADONE(ushort landCode) WHERE Landcode = #landcode">
</cf:method>
</cf:entity>
The generated code for the LoadByLandcode method looks like this:
public static Land LoadByLandcode(ushort landCode)
{
if ((landCode == CodeFluentPersistence.DefaultUInt16Value))
{
return null;
}
Land land = new Land();
CodeFluent.Runtime.CodeFluentPersistence persistence = CodeFluentContext.Get(BusinessLayerStoreName).Persistence;
persistence.CreateStoredProcedureCommand(null, "Land", "LoadByLandcode");
persistence.AddParameter("#landCode", landCode);
System.Data.IDataReader reader = null;
try
{
reader = persistence.ExecuteReader();
if ((reader.Read() == true))
{
land.ReadRecord(reader, CodeFluent.Runtime.CodeFluentReloadOptions.Default);
land.EntityState = CodeFluent.Runtime.CodeFluentEntityState.Unchanged;
return land;
}
}
finally
{
if ((reader != null))
{
reader.Dispose();
}
persistence.CompleteCommand();
}
return null;
}
As you can see CodeFluent returns null if the provided landCode parameter is 0. In order to avoid this check I have indicated that the landCode parameter is nullable:
<cf:method name="LoadByLandcode" body="LOADONE(ushort landCode?) WHERE Landcode = #landcode">
</cf:method>
or
<cf:method name="LoadByLandcode" body="LOADONE(ushort landCode) WHERE Landcode = #landcode">
<cf:parameter name="landCode" nullable="true" />
</cf:method>
Now in the BOM the check for 0 has been removed, but in the stored procedure a check for null on the landCode parameter has been added:
CREATE PROCEDURE [dbo].[Land_LoadByLandcode]
(
#landCode [smallint] = NULL
)
AS
SET NOCOUNT ON
IF (#landCode IS NULL)
BEGIN
SELECT DISTINCT [Land].[Land_Id], [Land].[Landcode], ...FROM [Land]
END
ELSE
BEGIN
SELECT DISTINCT [Land].[Land_Id], [Land].[Landcode], ... FROM [Land]
WHERE ([Land].[Landcode] = #landCode)
END
RETURN
I neither want a check for 0 in the BOM nor a check for NULL in the stored procedure. How can I achieve this?
To remove the default value check in the generated BOM, set cfom:checkDefaultValue="false".
<cf:method name="LoadByLandcode" body="LOADONE(ushort landCode) WHERE Landcode = #landcode">
<cf:parameter typeName="ushort" name="landCode" nullable="False" cfom:checkDefaultValue="false" modelNullable="False" usePersistenceDefaultValue="false" />
</cf:method>
If you use the graphical interface:
This generates:
public static Land LoadByLandcode(ushort landCode)
{
Land land = new Land();
CodeFluent.Runtime.CodeFluentPersistence persistence = CodeFluentContext.Get(Constants.StoreName).Persistence;
persistence.CreateStoredProcedureCommand(null, "Land", "LoadByLandcode");
persistence.AddRawParameter("#landCode", landCode);
System.Data.IDataReader reader = null;
try
{
reader = persistence.ExecuteReader();
if ((reader.Read() == true))
{
land.ReadRecord(reader, CodeFluent.Runtime.CodeFluentReloadOptions.Default);
land.EntityState = CodeFluent.Runtime.CodeFluentEntityState.Unchanged;
return land;
}
}
finally
{
if ((reader != null))
{
reader.Dispose();
}
persistence.CompleteCommand();
}
return null;
}
CREATE PROCEDURE [dbo].[Land_LoadByLandcode]
(
#landCode [smallint]
)
AS
SET NOCOUNT ON
SELECT DISTINCT [Land].[Land_Id], [Land].[Land_Landcode]
FROM [Land]
WHERE ([Land].[Land_Landcode] = #landCode)
RETURN
GO

Add OR condition to query

I am wondering how it is possible to add an OR condition to the Envers criteria api:
public IEnumerable<Guid> GetHistory(object id, params string[] props)
{
var auditQuery = AuditReaderFactory.Get(Session).CreateQuery()
.ForRevisionsOfEntity(typeof(T), false, true);
foreach (var prop in props)
{
auditQuery.Add(AuditEntity.RelatedId(prop).Eq(id)); // <-- adds AND, while OR is required!
}
return auditQuery
.GetResultList<object[]>()
.Select(i => ((T)i[0]).ID)
.Distinct();
}
Use AuditEntity.Disjunction().
In your example, something like...
[..]
var disjunction = AuditEntity.Disjunction();
foreach (var prop in props)
{
disjunction.Add(AuditEntity.RelatedId(prop).Eq(id));
}
auditQuery.Add(disjunction);
[..]
I did like this in Java as #Roger mentioned above. (Just in case if anybody needs)
public List<Employee> getAuditHistory(Session session, int id, String property) {
AuditReader auditReader = AuditReaderFactory.get(session);
List<Employee> employeeHistory = new ArrayList<>();
if (auditReader != null) {
AuditQuery auditQuery = auditReader.createQuery().forRevisionsOfEntity(Employee.class, true, false)
.add(AuditEntity.property(ResultsConstants.Employee_ID).eq(id));
AuditDisjunction auditDisjunction = null;
if (property.equalsIgnoreCase("FULL_NAME")) {
auditDisjunction = AuditEntity.disjunction().add(AuditEntity.property("FIRST_NAME".toUpperCase()).hasChanged())
.add(AuditEntity.property("LAST_NAME".toUpperCase()).hasChanged());
} else {
auditQuery = auditQuery.add(AuditEntity.property(property.toUpperCase()).hasChanged());
}
auditQuery = auditQuery.addOrder(AuditEntity.property("MODIFIED_DATE").desc());
if(null != auditDisjunction){
auditQuery = auditQuery.add(auditDisjunction);
}
if (auditQuery != null) {
if (auditQuery.getResultList().isEmpty()) {
// Log here or throw it back to caller
}
employeeHistory.addAll(auditQuery.getResultList());
}
}
return employeeHistory;
}

Strange behaviour with Plugin on Update of activity

I'm creating a plugin on creating a phonecall activity to update a field in the recipients contact entities. This plugin runs on Create and on Update of a phonecall activity.
On Create AND "new_targetfield" is null => Updates correctly
On Update AND "new_targetfield" not null => Updates correctly
On Update AND "new_targetfield" is null => Nothing happens
I tried running the Plugin Profiler but I keep getting an error:
<ErrorCode>-2147220970</ErrorCode>
<ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic
Here's a part of my code :
IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
{
Entity entity = context.InputParameters["Target"] as Entity;
if (entity.LogicalName != "phonecall")
{
return;
}
DateTime activitydate=entity.GetAttributeValue<DateTime>("actualstart");
if (activitydate ==null && context.MessageName =="Update")
{
activitydate=((Entity)context.PostEntityImages["PhoneCallPostImage"]).GetAttributeValue<DateTime>("actualstart");
}
if (activitydate != null)
{
// update recipients
EntityCollection Recipients = entity.GetAttributeValue<EntityCollection>("to");
if (Recipients == null && context.MessageName == "Update")
{
Recipients = ((Entity)context.PostEntityImages["PhoneCallPostImage"]).GetAttributeValue<EntityCollection>("to");
}
if (Recipients != null)
{
foreach (Entity recipient in Recipients.Entities)
{
EntityReference partyId = recipient.GetAttributeValue<EntityReference>("partyid");
if (partyId != null)
{
// get recipient id
if (partyId.LogicalName == "contact")
{
Guid contactid = partyId.Id;
// update the recipient Last Contacted with Phone call date
string fetch = #"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>
<entity name='contact'>
<attribute name='contactid' />
<attribute name='new_targetfield' />
<filter type='and'>
<condition attribute='contactid' operator='eq' uitype='contact' value='"+contactid+#"' />
</filter>
</entity>
</fetch>";
EntityCollection result = service.RetrieveMultiple(new Microsoft.Xrm.Sdk.Query.FetchExpression(fetch));
if (result.Entities.Count > 0)
{
DateTime lasttouched = result.Entities[0].GetAttributeValue<DateTime>("new_targetfield");
if (lasttouched != null)
{
if (activitydate > lasttouched)
{
Entity contact = new Entity();
contact.LogicalName = "contact";
contact.Id = contactid;
contact.Attributes = new AttributeCollection();
contact.Attributes.Add("new_targetfield", activitydate);
service.Update(contact);
}
else
{
continue;
}
}
else
{
Entity contact = new Entity();
contact.LogicalName = "contact";
contact.Id = contactid;
contact.Attributes = new AttributeCollection();
contact.Attributes.Add("new_targetfield", activitydate);
service.Update(contact);
}
}
}
else
{
continue;
}
}
else
{
continue;
}
}
}
The problem was that a DateTime variable will never be null but equal to the MinValue of DateTime. That's why parts of the code weren't approached.

How to get FootnoteRefrence Id in OpenXML using C#

I'm having a OOXML document's Paragraph Element like this.
Now i want the FootNoteRefrence id from this text programmatically using c#.
Text From the document.xml
<w:p>
<w:r>
<w:rPr>
<w:rStyle w:val="FootnoteReference" />
</w:rPr>
<w:footnoteReference w:id="2" />
</w:r>
</w:p>
C# Code
private BodyPara writePara(BodyPara bPara2, OpenXmlElement pTag)
{
Footnotes fn = null;
foreach (var run in pTag.Descendants<Run>())
{
if (run.HasChildren)
{
foreach (var runProp in run.Descendants<RunProperties>())
{
foreach (var runStyle in runProp.Descendants<RunStyle>())
{
if (runStyle.Val != null)
{
string runSty = runStyle.Val.Value;
if (runSty == "FootnoteReference")
{
if (fn != null)
{
bPara2.FootNotes.Add(fn);
}
fn = new Footnotes();
}
else if (runSty == "CommentReference")
{
}
else
{
if (fn != null)
{
fn.FootText = fn.FootText + run.InnerText;
}
}
}
}
//FootnotesPart footnotesPart = wordDoc.MainDocumentPart.FootnotesPart;
//if (footnotesPart != null)
//{
// IEnumerable<Footnote> footnotes = footnotesPart.Footnotes.Elements<Footnote>();
// ...
//}
if (runProp.NextSibling() != null)
{
OpenXmlElement fr = runProp.NextSibling();
foreach (var fnref in fr)
{
if (fnref != null)
{
// fn.FootnoteID = fnref.Id.Value.ToString();
}
}
}
foreach (var shd in runProp.Descendants<Shading>())
{
if (shd.Fill != null)
{
string shdvalue = shd.Fill.Value;
}
}
}
}
}
return bPara2;
}
I'm using this to get Footnote Reference id of Each footnote.
In this loop i cant get the Descendants of Run of Type FootNoteReference and also its value.
Pls Help me with this.
Thank You.
Sorry I did a mistake in the parameters, Instead of using Paragraph pTag in the parameter list, i used OpenXmlElement pTag. Now i changed it from generic to specific. It works for now.

Sorting on multiple column header in liferay searchcontainer

i done with sorting on single column header of liferay searchcontainer in liferay 6.0.6.
now i want to apply sorting on multiple fields i.e FirstName,LastName,Date either in asc or desc order.
can anybody help me out..
Thanks in advance....
view.jsp
<%
PortalPreferences portalPrefs = PortletPreferencesFactoryUtil.getPortalPreferences(request);
String orderByCol = ParamUtil.getString(request, "orderByCol");
String orderByType = ParamUtil.getString(request, "orderByType");
System.out.println("Col "+ orderByCol);
if (Validator.isNotNull(orderByCol) && Validator.isNotNull(orderByType)) {
portalPrefs.setValue("NAME_SPACE", "order-by-col", orderByCol);
portalPrefs.setValue("NAME_SPACE", "order-by-type", orderByType);
} else {
orderByCol = portalPrefs.getValue("NAME_SPACE", "order-by-col", "Date");
orderByType = portalPrefs.getValue("NAME_SPACE", "order-by-type", "asc");
}
%>
<liferay-ui:search-container delta='20' emptyResultsMessage="No Form Submitted" orderByCol="<%= orderByCol %>" orderByType="<%= orderByType %>">
<liferay-ui:search-container-results>
<%
List<User> userList = UserLocalServiceUtil.getUsers(-1,-1);
OrderByComparator orderByComparator =
CustomComparatorUtil.getUserOrderByComparator(orderByCol, orderByType);
Collections.sort(userList,orderByComparator);
results = ListUtil.subList(userList, searchContainer.getStart(),
searchContainer.getEnd());
if (userList.size()< total)
{total = userList.size();
}
pageContext.setAttribute("results", results);
pageContext.setAttribute("total", total);
%>
</liferay-ui:search-container-results>
<liferay-ui:search-container-row
className="com.liferay.portal.model.User"
modelVar="user">
<liferay-ui:search-container-column-text
name="Screen Name"
property="screenName"
orderable="<%= true %>"
orderableProperty="screenName"
/>
<liferay-ui:search-container-column-text
name="Email"
property="emailAddress"
orderable="<%= true %>"
orderableProperty="emailAddress"
/>
<liferay-ui:search-container-column-text
name="Date"
property="createDate"
orderable="<%= true %>"
/>
</liferay-ui:search-container-row>
<liferay-ui:search-iterator />
</liferay-ui:search-container>
CustomComparatorUtil
public static OrderByComparator getUserOrderByComparator(
String orderByCol, String orderByType) {
boolean orderByAsc = false;
if (orderByType.equals("asc")) {
orderByAsc = true;
}
OrderByComparator orderByComparator = null;
System.out.println("Custom "+ orderByCol);
if (orderByCol.equalsIgnoreCase("screenName")) {
System.out.println("1");
orderByComparator = new FirstNameComparator(orderByAsc);
}
else if (orderByCol.equalsIgnoreCase("emailAddress")) {
System.out.println("2");
orderByComparator = new EmailComparator(orderByAsc);
}
else if (orderByCol.equalsIgnoreCase("Date")) {
System.out.println("3");
orderByComparator = new DateComparator(orderByAsc);
}/*
else if (orderByCol.equalsIgnoreCase("Job Title")) {
orderByComparator = new JobTitleComparator(orderByAsc);
}*/
return orderByComparator;
}
FirstNameComparator
public static String ORDER_BY_ASC = "status ASC";
public static String ORDER_BY_DESC = "status DESC";
public FirstNameComparator()
{
this(false);
}
public FirstNameComparator(boolean asc) {
_asc = asc;
}
public int compare(Object obj1, Object obj2) {
User instance1 = (User) obj1;
User instance2 = (User) obj2;
int value = instance1.getFirstName().toLowerCase().compareTo(instance2.getFirstName().toLowerCase());
if(_asc)
{
return value;
} else
{
return -value;
}
}
public String getOrderBy() {
if (_asc) {
return ORDER_BY_ASC;
}
else {
return ORDER_BY_DESC;
}
}
private boolean _asc;
}
similarly u can make class for emailaddress and date..