0

I have a ReportParameter list called lstParam with few values.

List<ReportParameter> lstParam = new List<ReportParameter>();
ReportParameter rpm = new ReportParameter();    
rpm.Name = "Department";
rpm.Name = "Location";
lstParam.Add(rpm);

Note: ReportParameter is used from reporting services rdlobject model

Now I need to check if the list has a specific string value and the below code doesn't work for 'ReportParameter' list.

var matchingvalues = !lstParam.Where(stringToCheck => stringToCheck.Contains(stringValue));

if (!lstParam.Any(str => str.Contains(stringValue)))
  { 

  }

Both the above statement didn't help and I get the below error.

'ReportParameter' does not contain a definition for 'Contains' and the best extension 
method overload 'Queryable.Contains<string>(IQueryable<string>,string)' 
requires a receiver of type 'IQueryable<string>'

ReportParameter class:

public class ReportParameter : ReportObject, INamedObject
{
    public ReportParameter();

    [DefaultValue(false)]
    public bool AllowBlank { get; set; }
    public DataTypes DataType { get; set; }
    public DefaultValue DefaultValue { get; set; }
    [DefaultValue(false)]
    public bool Hidden { get; set; }
    [DefaultValue(false)]
    public bool MultiValue { get; set; }
    [XmlAttribute(typeof(string))]
    public string Name { get; set; }
    [DefaultValue(false)]
    public bool Nullable { get; set; }
    [ReportExpressionDefaultValueAttribute]
    public ReportExpression Prompt { get; set; }
    [DefaultValue("")]
    [XmlChildAttributeAttribute("Prompt", "LocID", "http://schemas.microsoft.com/SQLServer/reporting/reportdesigner")]
    public string PromptLocID { get; set; }
    [DefaultValue(UsedInQueryTypes.Auto)]
    public UsedInQueryTypes UsedInQuery { get; set; }
    public ValidValues ValidValues { get; set; }

    protected override bool RdlSemanticEqualsCore(ReportObject rdlObj, ICollection<ReportObject> visitedList);
}

Really appreciate any suggestions.

vicky
  • 107
  • 2
  • 10
  • ReportParameter is obviously not a string. Do you actually want to check against a particular string property of this object? – Andrei Nov 29 '16 at 12:18
  • Can you show the ReportParameter class what it contains? Based on that we have to decide the implementation. – Souvik Ghosh Nov 29 '16 at 12:19
  • @Andrei - Yes, I want to check string value with lstParam list. – vicky Nov 29 '16 at 12:19
  • @SouvikGhosh - Updated my post. – vicky Nov 29 '16 at 12:21
  • I think you wish to check either the property Name or PromptLocID of any of the items in the list contains the stringvalue. Am I right? Please Correct me if I'm wrong. – Sethu Bala Nov 29 '16 at 12:23
  • It might be something like this- var matchingvalues = !lstDSParameter.Where(stringToCheck => stringToCheck.Name.Contains(stringValue)); – Souvik Ghosh Nov 29 '16 at 12:24
  • Ya it could be either the way Souvik Ghosh has said above or it could be 'var matchingvalues = !lstDSParameter.Where(stringToCheck => stringToCheck.Name.Contains(stringValue) || stringToCheck.PromptLocID.Contains(stringValue))' if you wish to check for both – Sethu Bala Nov 29 '16 at 12:26
  • @SouvikGhosh - I am getting this error. `bool string.Contains(string value) (+ 2 overloads).Returns a value indicating whether the specified string object occurs within this string, Operator '!' cannot be applied to operand of type 'IEnumerable'` – vicky Nov 29 '16 at 12:30
  • @SethuBala - I am getting the same error mentioned in the above comment. – vicky Nov 29 '16 at 12:32
  • `ReportParameter` only contains the definition of the report parameter not its runtime value. – Wagner DosAnjos Nov 29 '16 at 12:33
  • How do you populate the `ReportParameter` list? Please post the respective code. – Wagner DosAnjos Nov 29 '16 at 12:38
  • It seems you are using the `ReportParameter` from the wrong namespace. Try using the one in the [Microsoft.ReportingServices.ReportRendering Namespace](https://msdn.microsoft.com/en-us/library/microsoft.reportingservices.reportrendering.aspx). This one contains a `Value` property. – Wagner DosAnjos Nov 29 '16 at 12:42

4 Answers4

1

If you want to check only if there ia any item that satisifes your condition, can you please try this code

bool matchingvalues = lstDSParameter.SelectMany(stringToCheck => stringToCheck.Name.Contains(stringValue) || stringToCheck.PromptLocID.Contains(stringValue)).ToList().Count > 0
Sethu Bala
  • 457
  • 3
  • 17
  • Error message is thrown at SelectMany. `Try specifying the type arguments explicitly` – vicky Nov 29 '16 at 12:44
  • bool matchingvalues = lstDSParameter.Any(stringToCheck => stringToCheck.Name.Contains(stringValue) || stringToCheck.PromptLocID.Contains(stringValue)); Can you please try this. This will return true if any item in the list satisfies either of the 2 conditions. – Sethu Bala Nov 29 '16 at 12:52
1

You describe two lists: lstParam and lstDSParameter. I assume that is a typo and they are the same list.

Each element in lstParam is of type ReportParameter. If you use Enumerable.Where, every item in the were clause represents a ReportParameter. A ReportParameter is not a string, and thus you get the compiler error you described.

You say that you need to check if the list has a specific string value.

Well obviously, because the list does not contain strings, there isn't any. Therefore I assume that you need to check if a certain property of the elements in the sequence contains a specific string value. Let's assume you want to check if any of the Names of the ReportParameters in the sequence contains the specific string value.

To do this, you have to transform every element in the sequence to a string that contains the Name value of each element. In Linq, whenever you need to transform elements from a sequence into something else you use Enumerable.Select:

List<ReportParameter> lstParam = ...;
var reportParameterNames = lstParam.Select(reportParameter => reportParameter.Name);

"From every reportParameter in lstParam, take reportParameter.Name, and put these names in a new sequence called reportParameterNames"

Now to check if any of the reportParameterNames equals the SpecificStringValue you can use Enumerable.Any:

bool lstParamContainSpecificStringValue = reportParameterNames
    .Any(name => name == SpecificStringValue);

"Check if any element in the reportParameterNames sequence equals SpecificStringValue"

This article helped me to understand LINQ, and learned me how to use it

Harald Coppoolse
  • 28,834
  • 7
  • 67
  • 116
  • There is only one list and to be clear this is what I want actually `bool lstParamContainSpecificStringValue = lstDSParameter.Any(name => name == rpmObj.Name);` rpmObj is one of the reportparamter value from another list. – vicky Nov 29 '16 at 12:57
1

It seems you are using the ReportParameter from the wrong namespace. Try using the one in the Microsoft.ReportingServices.ReportRendering Namespace. This one contains a Value property.

MSDN ReportParameter Class

So you can use it like this:

if (!lstParam.Any(p => p.Value?.ToString().Contains(stringValue)))
{ 

}
Wagner DosAnjos
  • 6,304
  • 1
  • 15
  • 29
  • how about using `Name` property from the existing class? – vicky Nov 29 '16 at 12:55
  • @vicky `Name` is the report parameter's name not its value. The question talks about checking for a specific **string value**, does that mean the parameter name or its value? You already know the names, right? Department and Location. – Wagner DosAnjos Nov 29 '16 at 12:59
0

have look at the question this.

may be reflection can help you here. I suggest you to 1st loop through the

    List<ReportParameter> lstParam = new List<ReportParameter>();
foreach(var item in lstParam )
{
//and then loop through class properties 
Type type = item.GetType();
PropertyInfo[] properties = type.GetProperties();

foreach (PropertyInfo property in properties )
{
    //now here you can play with class properties 
//like property.Name or property.Value
//place your check here
}
}

I haven't tested this code, just suggesting you the path to go. I hope this will help, trying to find some other efficiente way to get rid of loops.

Community
  • 1
  • 1
R K Sharma
  • 845
  • 8
  • 23
  • 42