How to fetch the PropertyTemplate by symbolic name and appended to Custom Object class IBM FileNet CE API - filenet-p8

How to fetch the PropertyTemplate by symbolic name and appended to Custom Object class through IBM FileNet CE API

You can use the following function to fetch the property template:
public PropertyTemplate getPropertyTemplate(String name, ObjectStore objectStore )
{
String queryFormat = "SELECT [This] FROM [PropertyTemplate] WHERE ([SymbolicName] = ''{0}'')";
SearchScope scope = new SearchScope( objectStore );
String query = MessageFormat.format(queryFormat, name );
RepositoryRowSet fetchRows = scope.fetchRows(new SearchSQL( query ), null, null, null );
Iterator<?> iterator = fetchRows.iterator();
if ( !iterator.hasNext() )
{
return null;
}
RepositoryRow row = (RepositoryRow) iterator.next();
return (PropertyTemplate) row.getProperties().getObjectValue("This");
}
And then use the following code to add the property template to the class:
PropertyTemplate propertyTemplate = getPropertyTemplate(name, objectStore);
ClassDefinition classDefinition = Factory.ClassDefinition.fetchInstance(objectStore, className, null);
PropertyDefinition propertyDefinition = propertyTemplate.createClassProperty();
// Set some additional properties on the property definition
// to override template defaults
classDefinition.get_PropertyDefinitions().add(propertyDefinition);
classDefinition.save(RefreshMode.NO_REFRESH);

Related

Error in processing entity WorkOrder unable to create entity object

I am receiving the following error calling GetAssetEquipmentOp:
"Error in processing entity WorkOrder unable to create entity object"
Here is the code so far:
public stringType getAssetDescription(string equipmentcode)
{
try
{
// Setup Service Objects
MP0302_GetAssetEquipment_001.GetAssetEquipmentService getservice = new MP0302_GetAssetEquipment_001.GetAssetEquipmentService();
MP0302_GetAssetEquipment_001.MP0302_GetAssetEquipment_001 getrequest = new MP0302_GetAssetEquipment_001.MP0302_GetAssetEquipment_001();
MP0302_GetAssetEquipment_001.MP0302_GetAssetEquipment_001_Result getresult = new MP0302_GetAssetEquipment_001.MP0302_GetAssetEquipment_001_Result();
// Setup Return Object
stringType desc = new stringType();
// Setup Service Parameters
getrequest.ASSETID = new MP0302_GetAssetEquipment_001.EQUIPMENTID_Type();
getrequest.ASSETID.EQUIPMENTCODE = equipmentcode;
getrequest.ASSETID.ORGANIZATIONID = new MP0302_GetAssetEquipment_001.ORGANIZATIONID_Type();
getrequest.ASSETID.ORGANIZATIONID.ORGANIZATIONCODE = _orgCodeBody;
// Setup Datastream Object
Datastream.EWS.Session sess = new Datastream.EWS.Session(_userid, _passwd, _orgCodeHead, _url, _tenant, false);
// Prepare Service Request
sess.PrepareServiceRequest(getservice);
// Call Web Service and get result
getresult = getservice.GetAssetEquipmentOp(getrequest);
// Extract Description
desc.stringValue = getresult.ResultData.AssetEquipment.ASSETID.DESCRIPTION;
desc.errorNum = 0;
// Close Up/Dispose
sess.CompleteServiceRequest(getservice);
sess.Dispose();
// Return value
return desc;
}
catch (Exception ex)
{
stringType errorStringType = new stringType();
errorStringType.errorNum = 1;
errorStringType.errorDesc = ex.Message;
return errorStringType;
}
}
I have checked the following:
- User group has interface permissions including BECONN
- User has "Connector" option selected
- User has status authorizations including * to Q for EVNT
Any help would be appreciated.
Problem solved! The problem was that the work order number did not exist. It is a very misleading error but once an existing work order was tested, it fetched the work order with no issues.

NHibernate IPostInsertEventListener : Insert executed multiple times

I am trying to test a simple NHibernate-based auditing mechanism that stores one row per changed property into a changelog table. What it actually does, is perform the actual insert statement as expected and perform the audit logging twice.
So, this is what I do:
string connectionString = #"Data Source=.\SQLEXPRESS;Initial Catalog=audittest;Integrated Security=SSPI;";
FluentConfiguration config = Fluently.Configure().Database(MsSqlConfiguration.MsSql2008
.ConnectionString(c => c.Is(connectionString)).ShowSql())
.Mappings(x => x.FluentMappings.Add<Class1ClassMap>())
.Mappings(x => x.FluentMappings.Add<ChangeLogMap>())
.ExposeConfiguration(cfg =>
{
NHibernateAuditListener listener = new NHibernateAuditListener();
cfg.AppendListeners(ListenerType.PostInsert, new[] { listener });
});
ISessionFactory sf = config.BuildSessionFactory();
ISession session = sf.OpenSession();
using (ITransaction tr = session.BeginTransaction())
{
session.Save(new Class1()
{
FirstName="Peter",
LastName="Pan",
Id=100
});
tr.Commit();
}
EDIT:
Altered the logging code to something simple to see the failure:
public void OnPostInsert(PostInsertEvent #event)
{
if (#event.Entity is IAuditable)
{
Console.WriteLine("----write audit----");
for (int index = 0; index < #event.State.Length; index++)
Console.WriteLine("----store changes of property {0}----",
#event.Persister.PropertyNames[index]);
}
}
This generates the following output:
NHibernate: INSERT INTO "Class1" (FirstName, LastName, Id) VALUES (#p0, #p1, #p2); #p0 = 'Peter' [Type: String (0)], #p1 = 'Pan' [Type: String (0)], #p2 = 1 [Type: Int64 (0)]
----write audit----
----store changes of property FirstName----
----store changes of property LastName----
----write audit----
----store changes of property FirstName----
----store changes of property LastName----
As you see, it's not the EventHandler code that's erroneous, but the framework calling it that behaves unexpectedly (calling the OnPostInsert method twice). Any ideas why this is happening?
SAMPLE PROJECT DOWNLOAD
Okay everybody, the problem exists in the detail of the handling within the programm. You are building up a FluentConfiguration-instance which on the fly creates the the basic NHibernate configuration.
This is done on the call of these 2 lines (variable config is of type FluentConfiguration):
new SchemaExport(config.BuildConfiguration()).Create(true, true);
and
ISessionFactory sf = config.BuildSessionFactory();
The FluentConfiguration caches the first created instance and reuses it for creating the new instance for the ISessionFactory-instance. On both calls the ExposeConfiguration of FluentConfiguration instance is called. So there are 2 instances of the NHibernateAuditListener within the session that is persisting the data.
Try it like this:
string connectionString = #"Data Source=.\SQLEXPRESS;Initial Catalog=audittest;Integrated Security=SSPI;";
var config = Fluently.Configure().Database(MsSqlConfiguration.MsSql2008
.ConnectionString(c => c.Is(connectionString)).ShowSql())
.Mappings(x => x.FluentMappings.Add<Class1ClassMap>())
.Mappings(x => x.FluentMappings.Add<ChangeLogMap>())
.ExposeConfiguration(cfg =>
{
NHibernateAuditListener listener = new NHibernateAuditListener();
cfg.AppendListeners(ListenerType.PostInsert, new[] { listener });
})
.BuildConfiguration();
new SchemaExport(config).Create(true, true);
Console.WriteLine("----------------------------------------------");
ISessionFactory sf = config.BuildSessionFactory();
ISession session = sf.OpenSession();
using (ITransaction tr = session.BeginTransaction())
{
session.Save(new Class1()
{
FirstName="Peter",
LastName="Pan",
Id=100
});
tr.Commit();
}
Within config you have now the real NHibernate Configuration instance, with only one Listener registered.
Got it?!

Linq in C# using IEnumerable

Appearently, I got an error if using the following code. It said:
Cannot implicity converrt type System.Linq.IQueryable<AnonymousType> to System.Collection.Generic.IEnumerable.
Please advise how I can fix this?
public IEnumerable<Session> GetAllListDetailConsumer(string refId)
{
ObjectQuery<Session> sessions = db.Sessions;
ObjectQuery<SessionsList> sessionsLists = db.SessionsList;
var query =
from s in sessions
join sList in sessionsLists on s.ReferralListID equals sList.ReferralListID
where s.ReferralListID == new Guid(refId)
select new SessionConsumerList
{
ReferralListID = s.ReferralListID,
SessionServerId = s.SessionServerID,
ApplicationID = s.ApplicationID,
// ...
ConsumerID = sList.ConsumerID,
ConsumerFirstName = sList.ConsumerFirstName,
ConsumerFamilyName = sList.ConsumerFamilyName,
// ...
};
return query.ToList();
}
You are selecting using select new, which would create an anonymous type, you need to project to class Session in your query like.
select new Session
{
....
But remember if your Session class is a representing a table in your database/data context, then you can't project to that class, instead you may have to create a temporary class and project the selection to that class.
EDIT (Since the question now has been edited)
Now you are selecting new SessionConsumerList and you are returning IEnumerable<Session>, you need to modify method signature to return IEnumerable<SessionConsumerList>
Why not separate the creation of the SessionConsumerList in another method? Makes the code a lot cleaner. Like this:
public static SessionConsumerList CreateSessionConsumerList(
Session s,
SessionsList sList)
{
return new SessionConsumerList
{
ReferralListID = s.ReferralListID,
SessionServerId = s.SessionServerID,
ApplicationID = s.ApplicationID,
// ...
ConsumerID = sList.ConsumerID,
ConsumerFirstName = sList.ConsumerFirstName,
ConsumerFamilyName = sList.ConsumerFamilyName,
// ...
};
}
And then:
var query =
from s in sessions
join sList in sessionsLists on s.ReferralListID equals sList.ReferralListID
where s.ReferralListID == new Guid(refId)
select CreateSessionConsumerList(s, sList);

LINQ performance when using nullable properties in select

I have an IEnumerable collection.
Using LINQ, I am populating the collection from a web service response.
Below is the sample I am using.
lookupData = from data in content["data"].Children()
select new LookupData
{
LookupKey = (data["data"]["key"]).ToString(),
LookupValue = (string)data["data"]["name"]
};
I will be using the same code for a lot of similar responses which will return a key and value.
Now, I got a scenario when I needed an additional field from the service response for few of the responses(not for all). So, I created an "Optional" property in "LookUpData" class and used as below:
lookupData = from data in content["data"].Children()
select new LookupData
{
LookupKey = (data["data"]["key"]).ToString(),
LookupValue = (string)data["data"]["name"],
Optional = referenceConfig.Optional != null
? (data["data"]["optional"]).ToString()
: String.Empty
};
The null check here is a performance issue. I do not want to use the below since I have other conditions and all together it will become a very big if else loop.
if(referenceConfig.Optional != null){
lookupData = from data in content["data"].Children()
select new LookupData
{
LookupKey = (data["data"]["key"]).ToString(),
LookupValue = (string)data["data"]["name"],
Optional = (data["data"]["optional"]).ToString()
};
}
else{
lookupData = from data in content["data"].Children()
select new LookupData
{
LookupKey = (data["data"]["key"]).ToString(),
LookupValue = (string)data["data"]["name"]
};
}
But I have at least 10 web server response with lots of data in each.
If the value of referenceConfig.Optional is available at compile time you can do
#if OPTIONAL
...
#else
...
If not - you can implement the Null Object Pattern i.e. have all of your ["data"][...] properties always return a value(for instance string.Empty if the type is string) so you won't have check explicitly in the code.

Getting property value based on its column attribute value

List<MyModel1> myModel1 = new List<MyModel1>();
MyUserModel myUserModel = new MyUserModel();
List<MyModel2> myModel2 = new List<MyModel1>();
myModel1 = m_Service1.GetMyModelFields();
myUserModel = m_Service2.GetMyUserDetails();
myModel2 = (from myModel1Field in myModel1
select new MyModel2 { FieldCaption = myModel1Field.FieldAlias,
FieldValue = "" }).ToList<MyModel2>();
myModel1Field.FieldAlias text will be same as value of one of the Column attribute of one of the property in myUserModel. So I have to search for the column atribute(Name) in myUserModel and get the corresponding property values and assign it to 'FieldValue'. If I can't find the value in myUserModel I can set 'FieldValue' as "NA"
One way to get the column attribute(Name) value of for a property is as below when I know the Property name.
myUserModel.GetType().GetProperty("FirstName").GetCustomAttributes(typeof(System.Data.Linq.Mapping.ColumnAttribute), false).Cast<System.Data.Linq.Mapping.ColumnAttribute>().Single().Name
But in my case Property name will not be known. I have to find the property based on the myModel1Field.FieldAlias value. How to go about this. Please suggest.
MyUserModel with one of it's properties
public class MyUserModel {
[Column(Name = "first_name", DbType = "varchar")]
public string FirstName { get; set; }
}
Now if myModel1Field.FieldAlias is 'first_name' then I have to search in MyUserModel for a property with Column attribute(Name) as first_name. If it exists i have to set it's value to 'FieldValue'. Else set 'FieldValue' as "NA".
If you want to get the value of a property and you only know the Name property of one of the ColumnAttribute attributes on it what you can do is this:
// Let's say you have the user model like so:
MyUserModel myUserModel = new MyUserModel { FirstName = "A", LastName = "B"};
// And then you want the value of the property that has the Column attribute Name "first_name"
string searchName = "first_name";
// Using some lambda you can do this (I do not know how to do this in LINQ syntax, sorry)
object propertyValue = typeof (MyUserModel).GetProperties()
.Where(p =>
{
var attrib = (ColumnAttribute)p
.GetCustomAttributes(typeof (ColumnAttribute), false)
.SingleOrDefault();
return (attrib != null &&
attrib.Name.Equals(searchName));
})
.Select(p => p.GetValue(myUserModel, null))
.FirstOrDefault();
if(propertyValue != null)
{
// Do whatever you want with the string "A" here - I suggest casting it to string! :-)
}
Is that what you want?

Resources