I am successfully retrieving a Table Row on Azure:
TableOperation operation = TableOperation.Retrieve<MyEntity>(partitionKey, rowkey);
TableResult result = table.Execute(operation);
if (result.Result != null)
{
}
I need to look at the Result to see if MyEntity.MyProperty == true
I cannot get to view the actual MyEntity result e.g.
log.Info(result.Result); returns Submission#0+MyEntity
log.Info(result.Result.MyProperty) : object does not contain a definition for MyProperty and no extension method MyProperty accepting a first argument of type 'object' could be found
With a TableResult, how do I see a property?
Just cast result.Result to your entity class:
((MyEntity)result.Result).MyProperty
Related
Here is what I exactly want to achieve but didn't have an answer. What's best practice to get the uid of CMSParagraphComponent on the storefront?
DefaultCMSComponentService
protected Collection<String> getEditorProperties(AbstractCMSComponentModel component, boolean readableOnly) {
String code = component.getItemtype();
if (!this.cEditorProperties.containsKey(code)) {
LOG.debug("caching editor properties for CMSComponent [" + component.getItemtype() + "]");
List<String> props = new ArrayList();
Collection<String> systemProps = this.getSystemProperties(component);
Set<AttributeDescriptorModel> attributeDescriptors = this.getTypeService()
.getAttributeDescriptorsForType(this.getTypeService().getComposedTypeForCode(code));
Iterator var8 = attributeDescriptors.iterator();
while (true) {
AttributeDescriptorModel ad;
String qualifier;
do {
do {
if (!var8.hasNext()) {
this.cEditorProperties.put(code, props);
return (Collection) this.cEditorProperties.get(code);
}
ad = (AttributeDescriptorModel) var8.next();
qualifier = ad.getQualifier();
} while (systemProps.contains(qualifier));
} while (readableOnly && !ad.getReadable());
props.add(qualifier);
}
} else {
return (Collection) this.cEditorProperties.get(code);
}
}
public Collection<String> getSystemProperties(AbstractCMSComponentModel component) {
String code = component.getTypeCode();
if (!this.cSystemProperties.containsKey(code)) {
LOG.debug("caching system properties for CMSComponent [" + component.getTypeCode() + "]");
List props = null;
try {
props = (List) Registry.getApplicationContext().getBean(code + "SystemProperties");
} catch (NoSuchBeanDefinitionException var5) {
LOG.debug("No bean found for : " + code + "SystemProperties", var5);
props = this.getSystemProperties();
}
this.cSystemProperties.put(code, props);
}
return (Collection) this.cSystemProperties.get(code);
}
It's not being populated because it's considered as the system property. Hence, as per the above logic system property will not be consider as redable property.
Now question is, How hybris get the list of system property for the given type? In another words, where this Registry.getApplicationContext().getBean(code + "SystemProperties") bean declare?
EDIT: The fact I know is, if Property attribute of AttributeDescriptor is set to false then it consider as system property. But when I checked for uid AttributeDescriptor, it (Property attribute) already set true.
There are some functionalities oob in hybris that uses the uid inside a view. For example the SearchPageController. To be more specific, let's take a look at this method :
private static final String COMPONENT_UID_PATH_VARIABLE_PATTERN = "{componentUid:.*}";
...
#ResponseBody
#RequestMapping(value = "/autocomplete/" + COMPONENT_UID_PATH_VARIABLE_PATTERN, method = RequestMethod.GET)
public AutocompleteResultData getAutocompleteSuggestions(...){
final SearchBoxComponentModel component = (SearchBoxComponentModel) cmsComponentService.getSimpleCMSComponent(componentUid);
}
The actual COMPONENT_UID_PATH_VARIABLE_PATTERN value is in the searchboxcomponent.jsp :
<spring:url value="/search/autocomplete/{/componentuid}" var="autocompleteUrl" htmlEscape="false">
<spring:param name="componentuid" value="${component.uid}"/>
</spring:url>
How does this work? Every time you type something, a call to this endpoint is made, with the component uid extracted using ${component.uid}.
Why does this work? Let's take a look at the productLayout1Page.jsp and take a simple tag from there:
<cms:pageSlot position="CrossSelling" var="comp" element="div" class="productDetailsPageSectionCrossSelling">
<cms:component component="${comp}" element="div" class="productDetailsPageSectionCrossSelling-component"/>
</cms:pageSlot>
Now we see that there is a <cms:component component=${..}.../> tag which reference a component instance and you can access it using ${component.attributeName} inside the component's jsp.
It seems not easy to get the uid on the storefront. But I have managed it like this
Create a dynamic attribute and return uid value from the getter method
Now you can populate this dynamic attribute on the frontend
I'm having difficulties creating a new ObjectMapper for Automapper (7.0.1)
I'm trying to create an Object mapper that take a source value and assign it to an object property so I can create a map between an int to a specific type of object.
So here is my MapExpression
public Expression MapExpression(IConfigurationProvider configurationProvider, ProfileMap profileMap,
PropertyMap propertyMap, Expression sourceExpression, Expression destExpression, Expression contextExpression)
{
var property = Property(destExpression, "Value");
return Assign(property, Convert(sourceExpression, property.Type));
}
sourceExpression DebugView
$resolvedValue
destExpression DebugView
.If ($dest == null) {
.Default(Prextra.Domain.SelectLists.SYS.StateSelectListItem) } .Else {
$typeMapDestination.State }
I don't know what I'm doing wrong, but I get this exception, so I guess it tries to assign the Int32 value to the object instead of the property?
InvalidOperationException: No coercion operator is defined between
types 'System.Int32' and
'Prextra.Domain.SelectLists.SYS.StateSelectListItem'
I'm dealing with something that seems to be a trivial task but haven't found a solution: How can I access the text on a RichSelectOneChoice? I've only found the values with richSelectOneChoice.getValue() and valueChangeEvent.getNewValue()
But, how is it possible to access the actual text?
My last attempt was this:
private RichSelectOneChoice selClaim;
public void claimTypeVCL(ValueChangeEvent ve){
Map s = selClaim.getAttributes();
Object ss = s.get(ve.getNewValue());
System.out.println(ss);
}
At the moment the console output is null for the corresponding value, no matter what the choice is.
The ADF component bound to the RichSelectOneChoice object is created as a component with inner elements.
I've also tried the solution proposed by Frank Nimphius here https://community.oracle.com/thread/1050821 with the proper object type (RichSelectOneChoice) but the if clause doesn't execute because the children are not instanceof RichSelectOneChoice as suggested but rather javax.faces.component.UISelectItem and this class doesn't include the getLabel() method and running the code actually throws a wide range of errors related either to casting an object to the target type or null pointers when trying to access the label.
Solved it using the UISelectionItem object and its getItemValue() and getItemLabel() methods instead of getLabel() or getValue(), the latter of which was available but didn't render the expected result.
The working code looks like this:
public String selectedOptionStr;
public void socClaimTypeVCL(ValueChangeEvent ve){
selectedOptionStr = "";
RichSelectOneChoice sct = (RichSelectOneChoice)ve.getSource();
List childList = sct.getChildren();
for (int i = 0; i < childList.size(); i++) {
if (childList.get(i) instanceof javax.faces.component.UISelectItem) {
javax.faces.component.UISelectItem csi = (javax.faces.component.UISelectItem) childList.get(i);
if (csi.getItemValue().toString() == ve.getNewValue().toString()) {
selectedOptionStr = csi.getItemLabel();
}
}
}
}
Using Entity Framework I can create concrete classes from most of the sprocs in the database of a project I'm working on. However, some of the sprocs use dynamic SQL and as such no metadata is returned for the sproc.
So for a that sproc, I manually created a concrete class and now want to map the sproc output to this class and return a list of this type.
Using the following method I can get a collection of objects:
var results = connection.Query<object>("get_buddies",
new { RecsPerPage = 100,
RecCount = 0,
PageNumber = 0,
OrderBy = "LastestLogin",
ProfileID = profileID,
ASC = 1},
commandType: CommandType.StoredProcedure);
My concrete class contains
[DataContractAttribute(IsReference=true)]
[Serializable()]
public partial class LoggedInMember : ComplexObject
{
/// <summary>
/// No Metadata Documentation available.
/// </summary>
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
[DataMemberAttribute()]
public global::System.Int16 RowID
{
get
{
return _RowID;
}
set
{
OnRowIDChanging(value);
ReportPropertyChanging("RowID");
_RowID = StructuralObject.SetValidValue(value);
ReportPropertyChanged("RowID");
OnRowIDChanged();
}
}
private global::System.Int16 _RowID;
partial void OnRowIDChanging(global::System.Int16 value);
partial void OnRowIDChanged();
[EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
[DataMemberAttribute()]
public global::System.String NickName
{
get
{
return _NickName;
}
set
{
OnNickNameChanging(value);
ReportPropertyChanging("NickName");
_NickName = StructuralObject.SetValidValue(value, false);
ReportPropertyChanged("NickName");
OnNickNameChanged();
}
}
private global::System.String _NickName;
partial void OnNickNameChanging(global::System.String value);
partial void OnNickNameChanged();
.
.
.
Without having to iterate through the results and add the output parameters to the LoggedInMember object, how do I map these on the fly so I can return a list of them through a WCF service?
If I try var results = connection.Query<LoggedInMember>("sq_mobile_get_buddies_v35", ... I get the following error:
System.Data.DataException: Error parsing column 0 (RowID=1 - Int64)
---> System.InvalidCastException: Specified cast is not valid. at Deserialize...
At a guess your SQL column is a bigint (i.e. Int64 a.k.a. long) but your .Net type has a n Int16 property.
You could play around with the conversion and ignore the stored procedure by doing something like:
var results = connection.Query<LoggedInMember>("select cast(9 as smallint) [RowID] ...");
Where you are just selecting the properties and types you want to return your object. (smallint is the SQL equivalent of Int16)
The solution to this was to create a complex object derived from the sproc with EF:
public ProfileDetailsByID_Result GetAllProfileDetailsByID(int profileID)
{
using (IDbConnection connection = OpenConnection("PrimaryDBConnectionString"))
{
try
{
var profile = connection.Query<ProfileDetailsByID_Result>("sproc_profile_get_by_id",
new { profileid = profileID },
commandType: CommandType.StoredProcedure).FirstOrDefault();
return profile;
}
catch (Exception ex)
{
ErrorLogging.Instance.Fatal(ex); // use singleton for logging
return null;
}
}
}
In this case, ProfileDetailsByID_Result is the object that I manually created using Entity Framework through the Complex Type creation process (right-click on the model diagram, select Add/Complex Type..., or use the Complex Types tree on the RHS).
A WORD OF CAUTION
Because this object's properties are derived from the sproc, EF has no way of knowing if a property is nullable. For any nullable property types, you must manually configure these by selecting the property and setting its it's Nullable property to true.
I am having some issues in the mapping mentioned in the title. Here are the details:
class MyDomain
{
public Iesi.Collections.Generic.ISet<SomeType> MySomeTypes{ get; set; }
....
}
class MyDTO
{
public IList<SomeTypeDTO> MySomeTypes{ get; set; }
...
}
The mapping:
Mapper.CreateMap<MyDomain, MyDTO>().ForMember(dto=>dto.MySomeTypes, opt.ResolveUsing<DomaintoDTOMySomeTypesResolver>());
Mapper.CreateMap<MyDTO, MyDomain>().ForMember(domain=>domain.MySomeTypes, opt.ResolveUsing<DTOtoDomainMySomeTypesResolver>());
The Resolvers:
class DomaintoDTOMySomeTypesResolver: ValueResolver<MyDomain, IList<SomeTypeDTO>>
{
protected override IList<SomeTypeDTO> ResolveCore(MyDomain source)
{
IList<SomeTypeDTO> abc = new List<DemandClassConfigurationDTO>();
//Do custom mapping
return abc;
}
}
class DTOtoDomainMySomeTypesResolver: ValueResolver<MyDTO, Iesi.Collections.Generic.ISet<SomeType>>
{
protected override Iesi.Collections.Generic.ISet<SomeType> ResolveCore(SystemParameterDTO source)
{
Iesi.Collections.Generic.ISet<SomeType> abc = new HashedSet<SomeType>();
//Do custom mapping
return abc;
}
}
Mapping from Domain to DTO works ok and as expected I get a MyDTO object with IList of "SomeTypeDTO" objects.
However mapping of the DTO to Domain throws the following error:
Exception of type 'AutoMapper.AutoMapperMappingException' was thrown.
----> AutoMapper.AutoMapperMappingException : Trying to map Iesi.Collections.Generic.HashedSet`1[SomeType, MyAssembly...] to Iesi.Collections.Generic.ISet`1[SomeType, MyAssembly...]
Exception of type 'AutoMapper.AutoMapperMappingException' was thrown.
----> System.InvalidCastException : Unable to cast object of type 'System.Collections.Generic.List`1[SomeType]' to type 'Iesi.Collections.Generic.ISet`1[SomeType]
What might I be doing wrong and what do the error messages imply? It almost seems that automapper is having some issues in mapping the ISet ( together with its concrete implementation HashedSet). My understanding is that in the above described scenario automapper should just use the ISet reference returned by "DTOtoDomainMySomeTypesResolver". I also don't see why I am getting the "cast from List to ISet error".
This is because AutoMapper currently doesn't support ISet<> collection properties. It works when the destination property of ISet<> is already instantiated (is not null), because the ISet<> actually inherits from ICollection<>, thus Automapper can understand that and will do the collection mapping properly.
It doesn't work when the destination property is null and is interface type. You get this error, because automapper actually found out it can be assigned from ICollection<> so it instantiates the property using generic List<>, which is default collection when automapper must create new collection property, but then when it tries to actually assign it, it will fail, because obviously List<> cannot be cast to ISet<>
There are three solution to this:
Create a feature request to support ISet<> collections and hope they will add it
Make sure the property is not null. Eg. instantiate it in constructor to empty HashSet<>. This might cause some troubles for ORM layers, but is doable
The best solution that I went with is to create custom value resolver, which you already have and instantiate the property yourself if it is null. You need to implement the IValueResolver, because the provided base ValueResolver will not let you instantiate the property. Here is the code snippet that I used:
public class EntityCollectionMerge : IValueResolver
where TDest : IEntityWithId
where TSource : IDtoWithId
{
public ResolutionResult Resolve(ResolutionResult source)
{
//if source collection is not enumerable return
var sourceCollection = source.Value as IEnumerable;
if (sourceCollection == null) return source.New(null, typeof(IEnumerable));
//if the destination collection is ISet
if (typeof(ISet).IsAssignableFrom(source.Context.DestinationType))
{
//get the destination ISet
var destSet = source.Context.PropertyMap.GetDestinationValue(source.Context.DestinationValue) as ISet;
//if destination set is null, instantiate it
if (destSet == null)
{
destSet = new HashSet();
source.Context.PropertyMap.DestinationProperty.SetValue(source.Context.DestinationValue, destSet);
}
Merge(sourceCollection, destSet);
return source.New(destSet);
}
if (typeof(ICollection).IsAssignableFrom(source.Context.DestinationType))
{
//get the destination collection
var destCollection = source.Context.PropertyMap.GetDestinationValue(source.Context.DestinationValue) as ICollection;
//if destination collection is null, instantiate it
if (destCollection == null)
{
destCollection = new List();
source.Context.PropertyMap.DestinationProperty.SetValue(source.Context.DestinationValue, destCollection);
}
Merge(sourceCollection, destCollection);
return source.New(destCollection);
}
throw new ArgumentException("Only ISet and ICollection are supported at the moment.");
}
public static void Merge(IEnumerable source, ICollection destination)
{
if (source == null) return;
var destinationIds = destination.Select(x => x.Id).ToHashSet();
var sourceDtos = source.ToDictionary(x => x.Id);
//add new or update
foreach (var sourceDto in sourceDtos)
{
//if the source doesnt exist in destionation add it
if (sourceDto.Key (sourceDto.Value));
continue;
}
//update exisiting one
Mapper.Map(sourceDto.Value, destination.First(x => x.Id == sourceDto.Key));
}
//delete entity in destination which were removed from source dto
foreach (var entityToDelete in destination.Where(entity => !sourceDtos.ContainsKey(entity.Id)).ToList())
{
destination.Remove(entityToDelete);
}
}
}
Then on your mapping use opt => opt.ResolveUsing(new EntitCollectionMerge<Entity,Dto>()).FromMember(x => x.ISetMember) or if you have lots of collection like this you can add them automatically to all of them via typeMaps.