API
Version 7.x > API > CMS Repeaters & LINQ View modes: 
User avatar
Member
Member
Swainy - 6/3/2013 6:45:11 AM
   
CMS Repeaters & LINQ
Hi everyone,

We currently have an open support ticket with Kentico support so hopefully we can resolve it sometime, but we like to use LINQ as an easy way to split out datasets or order datasets or for general manipulation of data that you get back from the API (e.g. findall's for filters/click buttons etc).

We are finding that if we use LINQ to manipulate our data and then try pass this data back into a CMS Repeater that it simply doesn't pick up any custom fields.

For example
TreeNodeDataSet tnds = TreeHelper.SelectNodes('/%',true,"CMS.MenuItem");
List<TreeNode> firstThreeTreeNodes = tnds.Take(3);
cmsRepeater.DataSource = firstThreeTreeNodes;
cmsRepeater.DataBind();

Now obviously I could achieve this by using the TopN property but I am just showing a really basic example.

Now the CMS Repeater reads in fine DocumentName but won't read in any of the custom fields when you Eval them in the repeater (even though if you inspect the objects in the immediate window they are in the dataset).

As I say I do have a support call open, i'm just wondering if anyone has come across this before or if anyone is using LINQ with their data and experienced anything similair?

Thanks,

Matt

User avatar
Kentico Support
Kentico Support
kentico_zdenekc - 6/21/2013 1:46:31 AM
   
RE:CMS Repeaters & LINQ
Hi,

What will happen if you try to use the same approach with standard Asp.NET Repeater? Have you tried that? Does/will it work?

Best regards,
Zdenek

User avatar
Member
Member
Swainy - 6/21/2013 3:40:15 AM
   
RE:CMS Repeaters & LINQ
Hi Zdenekc,

It works correctly if you pass it through a normal Asp.NET Repeater. It's just simply evalling the property.

However if you do use the standard ASP.NET repeater then obviously you can't use all of the kentico features and resolve macros etc. so I was very reluctant to do this.

We have however had success by passing in square brackets around the eval property name (to denote a datacolumn rather than a property).
e.g. Eval("[PropertyNameHere]");

Maybe this is the solution.

Thanks,
Matt

User avatar
Kentico Support
Kentico Support
kentico_zdenekc - 7/1/2013 2:55:52 AM
   
RE:CMS Repeaters & LINQ
Hi,

It sounds like that if it works, it might be the solution, but to explain it exactly...I'm not sure I (and devs I asked) fully understand the scenario, as you were first speaking about achieving it by TopN and now it's just the Eval again...
Please let me know if I can be of any further assistance.

Kind regards,
Zdenek C.

User avatar
Member
Member
Swainy - 7/1/2013 2:59:09 AM
   
RE:CMS Repeaters & LINQ
Hi Zdenek,

Basically it's just if you use LINQ on your dataset, if you pass it back in to the standard Kentico CMS Repeater and simply use Eval("Property") it doesn't work.

I just used TopN as a basic example of using LINQ on the dataset (by taking the top 3 things).

it doesn't matter what LINQ you use, it's the same result.

Thanks,
Matt

User avatar
Kentico Support
Kentico Support
kentico_zdenekc - 7/8/2013 9:39:14 AM
   
RE:CMS Repeaters & LINQ
Hi Matt,

I see... there is most probably some sort of conversion to an array type of returned data - the ability to read properties with name in square brackets by Eval method suggests that.

I have asked our core team about any specific conversions that are made when using LINQ and I'll let you know when I get more information.

Regards,
Zdenek

User avatar
Member
Member
pnmcosta - 12/12/2013 10:20:30 AM
   
RE:CMS Repeaters & LINQ
Any update on this?

I have a similar scenario, where previously we used a CMSRepeater with a Path query.

However, now we want to manually filter the data, so I though that constructing a TreeNode from the DataRow would solve it, but unfortunately keep getting:

[CMSAbstractTransformation.DataBind]: Object reference not set to an instance of an object.

Probably cause the transformation methods (e.g. GetDocument) are not working.

The helper method that queries for the next property:
public static object GetNextProperty(TreeNode currentProperty)
{
TreeProvider tree = new TreeProvider();
var ds = tree.SelectNodes(CMSContext.CurrentSiteName, currentProperty.Parent.NodeAliasPath + "%",
CMSContext.CurrentDocumentCulture.CultureCode, true, "Custom.Property");
if (!DataHelper.DataSourceIsEmpty(ds)
&& ds.Tables[0].Rows.Count > 1)
{
int i = 0;
foreach (DataRow item in ds.Tables[0].Rows)
{
if (item["NodeAliasPath"].ToString() == currentProperty.NodeAliasPath)
break; // current!
i++;
}

i = i + 1; // next!

if (i >= ds.Tables[0].Rows.Count) // last?
i = 0; // first!

return new TreeNode[] { TreeNode.New(ds.Tables[0].Rows, "Custom.Property", tree) };
}
return null;
}

The repeater in a web part
     <cms:CMSRepeater ID="repRelated" runat="server" 
TransformationName="Custom.Property.propertylistitem_other"
DelayedLoading="true" DataBindByDefault="false" />

The method to bind the repeater invoked in the web parts Page_Load event
private void BindRepeater()
{
repRelated.DataSource = PropertyFunctions.GetNextProperty(CurrentDocument);
repRelated.ReloadData(true);
}

The transformation "Custom.Property.propertylistitem_other":

<div class="property-other">
<a href="<%# GetPropertyDetailUrl(true) %>"><%# IfImage("PropertyThumbnail", GetImage("PropertyThumbnail", 220), "<img src=\"~/App_Themes/Custom/Images/property_no_image.jpg\" alt=\"" + HTMLEncode(Eval("PropertyTitle").ToString()) + "\" />") %></a>
<div class="clearfix">
<%# IfId(Eval("PropertyAreaId"), "<h3 class='left'>" + GetPropertyAreaName(Eval("PropertyAreaId")) + "</h3>") %>
<h3 class="right"><%# GetPropertyPriceFormatted()%></h3>
</div>
<h2><a href="<%# GetPropertyDetailUrl(true) %>"><%# HTMLEncode(Eval("PropertyTitle").ToString()) %></a></h2>

</div>

Any help on trying to get the transformations to work on a manually bound repeater would be great!