Error An explicit conversion exists C#, MVVM Light - LINQ - c#

I am learning MVVM Light and the app I am working on has a functionality to search for event names. Here are my codes for filtering a ListBox as the user types into TextBox.
The error is: Cannot implicitly convert type 'System.Collections.Generic.IEnumerable<NGO_Volunteer_Comm_Platform_v1._0.DataModel.Event>' to 'System.Collections.Generic.List<NGO_Volunteer_Comm_Platform_v1._0.DataModel.Event>'. An explicit conversion exists (are you missing a cast?)
ViewModel codes:
private static ObservableCollection<Event> _searchEventCollection = new ObservableCollection<Event>();
public static ObservableCollection<Event> SearchEventCollection
{
get { return _searchEventCollection; }
set { _searchEventCollection = value; }
}
//search from homepage event section
private RelayCommand _eventSearch;
/// <summary>
/// Gets the EventSearch.
/// </summary>
public RelayCommand EventSearch
{
get
{
return _eventSearch
?? (_eventSearch = new RelayCommand(
async () =>
{
SearchEventCollection.Clear();
var eventList = await App.MobileService.GetTable<Event>().ToListAsync();
foreach (Event ename in eventList)
{
SearchEventCollection.Add(new Event
{
Id = ename.Id,
EventName = ename.EventName,
Date = ename.Date,
Location = ename.Location,
Desc = ename.Desc
});
}
}));
}
}
private string filter;
public String Filter
{
get
{
return this.filter;
}
set
{
this.filter = value;
RaisePropertyChanged("SearchEventCollection");
}
}
public List<Event> FilteredNames
{
get
{
return (from name in SearchEventCollection where name.EventName.StartsWith(filter) select name);
}
}
public searchfromhomepageViewModel()
{
filter = "";
}
How do I resolve this error?

Use the ToList extension method to create a List<T> from an IEnumerable<T>:
public List<Event> FilteredNames
{
get
{
return (from name in SearchEventCollection where name.EventName.StartsWith(filter) select name).ToList();
}
}
Or change the type of the FilteredNames property to IEnumerable<Event>. Actually, that's probably a better idea. In general, you shouldn't expose concrete collection types publicly, because it doesn't let you return an instance of a different type if you need to change it later. Also, returning a List<T> seems to imply that you can modify the list. But since a new list is returned each time the property is called, modifying it will have no effect on the property, so it's misleading.

Related

How to get a property value of a class defined inside of another class through a reflection

I have a MerchantWSBO and MerchantWSVO classes.
MerchantWSBO has a property of a type of MerchantWSVO.
I need to get a value of the property of a MerchantWSVO.
So, I have a code defining both classes(classes are coming through a WebReference from a 3rd party)
public MerchantWSBO {
private MerchantWSVO overviewField;
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public MerchantWSVO overview {
get {
return this.overviewField;
}
set {
this.overviewField = value;
}
}
}
public MerchantWSVO{
private System.Nullable<bool> discoverRetainedField;
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool discoverRetainedSpecified {
get {
return this.discoverRetainedFieldSpecified;
}
set {
this.discoverRetainedFieldSpecified = value;
}
}
}
I have the following method where I need to get the property value of dicoverRetained using reflection:
private string ClassToXML(Object classObject)
{
MerchantTest mt = new MerchantTest();
if(classObject is MerchantWSBO)
{
classObject.GetType().GetProperty("overviewField").GetValue(new MerchantWSVO, null);
mt.overview.discoverRetained = //need to get the value
}
var myString = new System.IO.StringWriter();
var serializer = new XmlSerializer(classObject.GetType());
serializer.Serialize(myString, classObject);
return myString.ToString();
}
Based on a parameter classObject which in this case can be of two types, I need to get a value from a property.
How can I do that?
You don't need reflection at all, simply cast the object to the correct type. Pattern matching helps here.
if(classObject is MerchantWSBO wsbo)
{
Console.WriteLine(wsbo.overview.discoverRetained);
}
or on older C# versions:
var wsbo = classObject as MerchantWSBO;
if(wsbo != null)
{
Console.WriteLine(wsbo.overview.discoverRetained);
}

c# GroupPrincipal.FindByIdentity finds the group, but when using GetMembers getting error - there is no such object on the server

this code used to work fine for the past year,
now it is still working, but i have only 4 groups that generate this error...
the code is simple:
using (var context = new PrincipalContext(ContextType.Domain, domName))
{
foreach (string grp in myGroups)
{
using (var group = GroupPrincipal.FindByIdentity(context, IdentityType.Name, grp))
{
PrincipalSearchResult<Principal> usersList;
usersList = group.GetMembers(true);
int usersListCount = usersList.Count();
}}}
when these specific groups come to search , i get the group and can see its description in the group object variable, but when getting its members i get an error massage :
base: "There is no such object on the server.\r\n"
ErrorCode: -2147016656
again,this happens only with 4 specific groups from the same domain, and same OU.
this just started a few days ago without me changing anything, not permissions, nothing in the code, very strange...
any ideas ?
When I encountered this problem I could not have an empty group. I had to produce "best possible" results while the network people were working to resolve the "foreign SID" issue.
I know it is a lot extra but it satisfied the auditors so maybe it will help you. This is what I did:
Precursor: I had already built a class that held all the properties of the AD Entity.
Got a list of users and all their group memberships.
Wrapped the call to get members in a try... catch and when this error occurred I inserted a "Group Membership" property of "Error Retrieving members"
When I had iterated through all the Groups I grabbed a list of all groups that had the error message as a group member then queried the Users list to get a list of all the users who were members of that group.
Then inserted Property records with the found users names.
Since this answer is more about solution structure I will only give a very brief outline of the classes used. While far from elegant it gave me a reusable container that was easy to understand and share and provided a solution that was durable across several networks. It probably lacks in many ways but it passes test #1 - it worked.
public class ADPropEntry : IComparable<ADPropEntry>
{
#region Properties
public string Name { get { return _name; } set { _adName = value; SetPropVals(_adName); } }
public string Value { get { return _v; } set { _v = value; DoValConversion(); } }
public bool IsVisible { get { return _isVis; } set { _isVis = value; } }
public string ConvertTo { get { return _convertVal; } set { _convertVal = value; } }
public int ID { get { return _id; } set { _id = value; } }
#endregion
private void SetPropVals(string s)
{
switch (s)
{
case "accountexpires": _name = "Account Expires"; _isVis = false; _convertVal = "FromFileTime"; break;
... more handles each property conversion
}
}
}
public class ADEntity : IComparable<ADEntity>
{
#region Properties
public string Name { get { return _name; } set { _name = value; } }
public List<ADPropEntry> MyProperty { get { return _ade; } set { _ade = value; } }
public string EntityType { get { return _entT; } set { _entT = value; } }
public string ADName { get { return GetProperty("SAM Account Name"); } }
#endregion
}
This formed provided me a durable data container and then I used another class to query AD in whatever method makes sense. This was packaged in a DLL that the client application could use.
class ADAccess
{
#region Properties
public bool HasErrors { get { return (bool)(_errMsg.Length > 10); } }
public string ErrorMsg { get { return _errMsg; } }
public List<ADEntity> GroupEntries { get { return _lstGrps; } }
public List<ADEntity> UserEntries { get { return _lstUsrs; } }
public List<ADEntity> PrinterEntries { get { return _lstPrts; } }
public List<ADEntity> ComputerEntries { get { return _lstCmps; } }
#endregion
public List<ADEntity> GetADListByMSO(string groupType)
{
if (groupType == "")
{
// get them all return an empty list populating properties
}
else
{
// set the context and fetch return populated list
}
}
Used the same structure to report on SQL server permissions as well.
i found out the issue,
the problematic groups contained users from different domains,
once removed these users from the groups , everything went back to work.
thanks.

List Filtering performance issue in wpf C# Viewmodel

I came across a performance issues when doing normal list filtering using FirstOrDefault. I am getting the data from the server in <2ms but the filtering takes 15,252 ms.This looks strange to me and I will be glad if someone could help me on this.
Here is the method and this line Loginaccess = loginlist.FirstOrDefault(x => x.LogName == LogTitle); takes 15,252 ms to execute.
private void GetData()
{
LoginServices obj = new LoginServices();
loginlist = obj.getlogins();
Loginaccess = loginlist.FirstOrDefault(x => x.LogName == LogTitle);
}
Here is how the list and Entity type is declared
public List<LoginEntity> loginlist
{
get;
set;
}
private LoginEntity _loginaccess;
public LoginEntity Loginaccess
{
get { return _loginaccess; }
set
{
_loginaccess = value;
}
}

How to add object to list item in c#

I have following classes:
public class QualifyResponse
{
List<ProviderQualifyResponse> _providerList = new List<ProviderQualifyResponse>();
public List<ProviderQualifyResponse> ProviderList
{
get { return _providerList; }
set { _providerList = value; }
}
}
public class ProviderQualifyResponse
{
private string _providerCode = string.Empty;
public string ProviderCode
{
get { return _providerCode; }
set { _providerCode = value; }
}
private List<QuestionGroup> _questionGroupList = new List<QuestionGroup>();
public List<QuestionGroup> QuestionGroupList
{
get { return _questionGroupList; }
set { _questionGroupList = value; }
}
}
I have QualifyResponse object which is populated with ProviderQualifyResponse but QuestionGroupList is empty. Now I want to fill QuestionGroupList. When I try to do it like this:
QualifyResponse qualifyResponse = response;
qualifyResponse.ProviderList.QuestionGroupList = new List<DataTypes.BuyFlow.Entities.QuestionGroup>();
I get error:
System.Collections.Generic.List' does not
contain a definition for 'QuestionGroupList' and no extension method
'QuestionGroupList' accepting a first argument of type
'System.Collections.Generic.List' could be
found (are you missing a using directive or an assembly reference?)
How can I add a List<QuestionGroup> to my qualifyResponse.ProviderList?
The error is this expression:
qualifyResponse.ProviderList.QuestionGroupList
ProviderList is of type List. You'll have to change it so you populate the correct item. Something like this:
int index = ...;
qualifyResponse.ProviderList[index].QuestionGroupList = ...
Problem is that QuestionGroupList is property of class ProviderQualifyResponse and if you want to add List, you need to assign it to property of object.
Example how to do that for all providers:
QualifyResponse qualifyResponse = response;
foreach(var provider in qualifyResponse.ProviderList)
{
provider.QuestionGroupList = new List<DataTypes.BuyFlow.Entities.QuestionGroup>();
}
Given that qualifyResponse.ProviderList is of type List<ProviderQualifyResponse>, you are trying to access List.QuestionGroupList, which doesn't exist as the error states.
You'll either need to iterate through the instances in the list to access the instance properties, if that's your intention, or select an instance from the list you wish to instantiate.
QualifyResponse qualifyResponse = response;
foreach (var providerQualifyResponse in qualifyResponse.ProviderList)
{
providerQualifyResponse.QuestionGroupList = new List<DataTypes.BuyFlow.Entities.QuestionGroup>();
}

Replace a collection item using Linq

How do I find and replace a property using Linq in this specific scenario below:
public interface IPropertyBag { }
public class PropertyBag : IPropertyBag
{
public Property[] Properties { get; set; }
public Property this[string name]
{
get { return Properties.Where((e) => e.Name == name).Single(); }
//TODO: Just copying values... Find out how to find the index and replace the value
set { Properties.Where((e) => e.Name == name).Single().Value = value.Value; }
}
}
Thanks for helping out in advance.
Do not use LINQ because it will not improve the code because LINQ is designed to query collection and not to modify them. I suggest the following.
// Just realized that Array.IndexOf() is a static method unlike
// List.IndexOf() that is an instance method.
Int32 index = Array.IndexOf(this.Properties, name);
if (index != -1)
{
this.Properties[index] = value;
}
else
{
throw new ArgumentOutOfRangeException();
}
Why are Array.Sort() and Array.IndexOf() methods static?
Further I suggest not to use an array. Consider using IDictionary<String, Property>. This simplifies the code to the following.
this.Properties[name] = value;
Note that neither solution is thread safe.
An ad hoc LINQ solution - you see, you should not use it because the whole array will be replaced with a new one.
this.Properties = Enumerable.Union(
this.Properties.Where(p => p.Name != name),
Enumerable.Repeat(value, 1)).
ToArray();
[note: this answer was due to a misunderstanding of the question - see the comments on this answer. Apparently, I'm a little dense :(]
Is your 'Property' a class or a struct?
This test passes for me:
public class Property
{
public string Name { get; set; }
public string Value { get; set; }
}
public interface IPropertyBag { }
public class PropertyBag : IPropertyBag
{
public Property[] Properties { get; set; }
public Property this[string name]
{
get { return Properties.Where((e) => e.Name == name).Single(); }
set { Properties.Where((e) => e.Name == name).Single().Value = value.Value; }
}
}
[TestMethod]
public void TestMethod1()
{
var pb = new PropertyBag() { Properties = new Property[] { new Property { Name = "X", Value = "Y" } } };
Assert.AreEqual("Y", pb["X"].Value);
pb["X"] = new Property { Name = "X", Value = "Z" };
Assert.AreEqual("Z", pb["X"].Value);
}
I have to wonder why the getter returns a 'Property' instead of whatever datatype .Value, but I'm still curious why you're seeing a different result than what I am.

Categories