LINQ Query Result - dynamically get field value from a field name variable - linq

LINQ newbie here
I am trying to get a value of a field - using a fieldName variable.
If I do a watch on row[FieldName] I do get a value - but when I do it on the actual code it will not compile.
string fieldName = "awx_name"
List<awx_property> propertyQry =
(
from property in crm.awx_propertyawx_properties
where property.awx_propertyid == new Guid(id)
select property
).ToList();
foreach (awx_property row in propertyQry)
{
//THIS DOES NOT WORK
fieldValue = row[fieldName];
}
Thanks in advance. Alternatives would be welcome as well

You keep us guessing what you are trying to do here... You need to specify the types of the objects, so it's easy for us to understand and help. Anyway, I think you are trying to get an object based on the ID. Since you are getting by Id, my guess would be the return value is a single object.
var propertyObj =( from property in crm.awx_propertyawx_properties
where property.awx_propertyid == new Guid(id)
select property
).SingleOrDefault();
if(propertyObj != null) {
fieldValue = propertyObj.GetType().GetProperty(fieldName).GetValue(propertyObj, null);
}
Of course, you need to add validation to make sure you don't get null or any other error while accessing the property value.
Hope it helps.

What type is fieldValue? What does awx_property look like? This will only work is awx_property is a key/value collection. It its not, you could use reflection instead.
If it is a key/value collection you are probably missing a cast. (row[FieldName].ToString() or something) Also you are missing a semi-colon in the foreach block.

Related

Method Syntax in LINQ: try to use variables in a long query

LINQ newbie here.
I have a long LINQ query, called it MYLONGQUERY, that returns a collection of certain class instances. If the list is not empty, I want to return a property (MYPROPERTY) of the first instance; otherwise it returns some default value (DEFAULTPROPERTY). So the query looks like this
(0 != MYLONGQUERY.count()) ? MYLONGQUERY.FirstOrDefault().MYPROPERTY: DEFAULTPROPERTY
This works fine. However, I don't like the fact that I have to repeat MYLONGQUERY before and after "?". I have been trying Let and Into, but have not been able to get those to work. And it has to be Method Syntax, not Query Syntax. Suggestions? Appreciate it.
You have to select the property first, then you can specify the default-value with DefaultIfEmpty:
var prop = MYLONGQUERY
.Select(x => x.MYPROPERTY)
.DefaultIfEmpty(DEFAULTPROPERTY) // new default-value
.First(); // never exception

How do I return multiple xml elements/ attributes with linq, and create objects with them?

I'm working with an xml document in C# that has multiple (100+) points of stock market data. I'd like to create objects and add them to a List<> by passing initialization values retrieved from an xml document via linq. At the moment I'm just able to run a linq query and return one of the xml fields, in the code below, the attribute "symbol." I'd also like to return the document's "LastTradeDate, DaysLow, DaysHigh, LastTradePriceOnly, Open, and Volume." From there, my custom constructor is: StockDataPoint(Symbol, TradeDate, Open, High, Low, Close, Volume). A nudge in the right direction would be great. Here's the current linq:
var makeInfo =
from s in doc.Descendants("quote")
where s.Element("LastTradeDate") != null
&& s.Attribute("symbol") != null
let dateStr = s.Element("LastTradeDate").Value
where !string.IsNullOrEmpty(dateStr)
&& DateTime.Parse(dateStr, enUS) == targetDate
select s.Attribute("symbol").Value;
Well it depends on your XML format, but you might just want something like:
...
select new StockDataPoint((string) s.Attribute("symbol"),
(DateTime) s.Attribute("TradeDate"),
(decimal) s.Attribute("Open"),
(decimal) s.Attribute("High"),
(decimal) s.Attribute("Low"),
(decimal) s.Attribute("Close"),
(long) s.Attribute("Volume"));
Note that by use the explicit operators on XAttribute, you can avoid performing the parse yourself. Indeed, you can use this earlier in your query too:
var makeInfo = from s in doc.Descendants("quote")
where s.Attribute("symbol") &&
(DateTime?) s.Attribute("LastTradeDate") == targetDate
select ...
If the target of the cast is a nullable type (either a nullable value type or a reference type) then if the attribute is missing, the result will be the null value for that type, which is very handy.
You need to create a class:
select new YourClass {
Symbol = s.Attribute("symbol").Value,
...
}

linq problem with distinct function

I am trying to bind distinct records to a dropdownlist. After I added distinct function of the linq query, it said "DataBinding: 'System.String' does not contain a property with the name 'Source'. " I can guarantee that that column name is 'Source'. Is that name lost when doing distinct search?
My backend code:
public IQueryable<string> GetAllSource()
{
PromotionDataContext dc = new PromotionDataContext(_connString);
var query = (from p in dc.Promotions
select p.Source).Distinct();
return query;
}
Frontend code:
PromotionDAL dal = new PromotionDAL();
ddl_Source.DataSource = dal.GetAllSource();
ddl_Source.DataTextField = "Source";
ddl_Source.DataValueField = "Source";
ddl_Source.DataBind();
Any one has a solution? Thank you in advance.
You're already selecting Source in the LINQ query, which is how the result is an IQueryable<string>. You're then also specifying Source as the property to find in each string in the databinding. Just take out the statements changing the DataTextField and DataValueField properties in databinding.
Alterantively you could remove the projection to p.Source from your query and return an IQueryable<Promotion> - but then you would get distinct promotions rather than distinct sources.
One other quick note - using query syntax isn't really helping you in your GetAllSources query. I'd just write this as:
public IQueryable<string> GetAllSource()
{
PromotionDataContext dc = new PromotionDataContext(_connString);
return dc.Promotions
.Select(p => p.Source)
.Distinct();
}
Query expressions are great for complicated queries, but when you've just got a single select or a where clause and a trivial projection, using the dot notation is simpler IMO.
You're trying to bind strings, not Promotion objects... and strings do not have Source property/field
Your method returns a set of strings, not a set of objects with properties.
If you really want to bind to a property name, you need a set of objects with properties (eg, by writing select new { Source = Source })

Dynamic Linq - no property or field exists in type 'datarow'

I am using Northwind Customers Table where I fill the dataset and get the datatable.
I am trying to use dynamic linq and want to select columnName dynamically
var qry = MyDataTable.AsEnumerable().AsQueryable().Select("new(Country)");
Right now I have hard coded country but even then I get this error
No property or field 'Country' exists in type 'datarow'
I would like to eventually change this query to take the column name dynamically.
Please help!!! thanks.
The important hint is here (in bold):
No property or field 'Country' exists
in type 'datarow'
The extension method AsEnumerable of the DataTable class returns an IEnumerable<T> where T has the type DataRow. Now the Select method of Dynamic LINQ wants to work with this type DataRow which hasn't a property Country of course.
You could try this instead:
var qry = MyDataTable.AsEnumerable().AsQueryable()
.Select("new(it[\"Country\"] as CountryAlias)");
it now represents a variable of type DataRow and you can use methods of this type and perhaps also the indexer in my example above. (Dynamic LINQ supports accessing array elements by an integer index, but I am not sure though if accessing an indexer with a string key will work.)
I've used Slauma's answer and it worked. In addition i was doing OrderBy with dynamic linq maybe this will help to someone. I'll just drop the code here.
string dynamicLinqText = $"it[\"{sortColumnName}\"] {sortDirection}"; //it["PERSON_NAME"] asc
result = result.AsEnumerable().OrderBy(dynamicLinqText).CopyToDataTable();

Subsonic 3 Newtonsoft JSON "Self referencing loop Exception"

Hi I been searching for my error but I can't find anything that help me. The problem is this. I been working with Subsonic 3, Newtonsoft Json and the linq way of write so I have this easy query:
var found = from client in newclients.All() where client.Period == "sometext" select client;
string periodoJSON = JsonConvert.SerializeObject(periodoFound); //this get "Self referencing loop Exception"
the problem is when I run this script I get the horrible exception "Self referening loop exception" in the JsonConvert line, subsonic have all the objects without any problem but if I do the following.
var found = from client in newclients.All() where client.Period == "sometext" select new client{client.Name, client.LastName, etc};
string periodoJSON = JsonConvert.SerializeObject(periodoFound);
I get the object serialize with a any problem with all the properties. I'm doing the last way because I have to finish my work but is any other way or solution for this problem, if not I will have to write all the properties every time I want to get a full table properties.
hope any can solve my problem o help me in the path for find a solution....
what I have is a really basic query with linq and I try the three values for JsonSerializerSettings and any work, again I'm working with subsonic 3 this not happend either with subsnoic 2 and I can make it work if I specify one by one the properties of the object in the linq query does any have any clue of what is happend, ANY more help would be great!!! If I put the value of Serialize my page get crazy and in a infinity loop state, if I decide for error simple doesn't work and Ignore nothing happen... some more information about this self referencia loop?
var u = usuario.SingleOrDefault(x => x.TipoUsuario == "A" || x.TipoUsuario == "W");
JsonSerializerSettings setting = new JsonSerializerSettings();
setting.ReferenceLoopHandling = ReferenceLoopHandling.Error; //.Serialize .Ignore
Page.ClientScript.RegisterClientScriptBlock(this.GetType(),"usuario", "var usuario=" + JsonConvert.SerializeObject(u, Formatting.None, setting) + ";");
Update ------
I code the following
string jsU = JsonConvert.SerializeObject(u,Formatting.None,new JsonSerializerSettings { PreserveReferencesHandling = PreserveReferencesHandling.Objects, ReferenceLoopHandling = ReferenceLoopHandling.Ignore });
and is workign but the only thing wrongs is that in the json object comes all the information about the columns of subsonic 3 and a BIG chunk of text explain it... does any one know how to not SEND this part of the object??
Without knowing more about you object model it is hard to provide a definitive answer, but I would take a look at the ReferenceLoopHandling enum.
You're calling string SerializeObject(object value) on JsonConvert. Try the string SerializeObject(object value, Formatting formatting, JsonSerializerSettings settings) method instead. The JsonSerializerSettings settings parameter lets you set a bunch of things, including the ReferenceLoopHandling ReferenceLoopHandling { get; set; } property.
You can try these values:
public enum ReferenceLoopHandling
{
Error,
Ignore,
Serialize
}
Obviously, Error is the default and that's what you're getting. Perhaps one of the others will help.

Resources