Dynamic LINQ error in Where clause - linq

I'm trying to do a Dynamic LINQ like in the ScotGu's blog
var select = db.San_Imovel.Where("Imovel_Id = #0", 123).Select("new(Imovel_Id)");
but I get the error
the best overloaded method match for '.Where(string, System.Data.Objects.OBjectsParameter[])' has some invalid arguments

Are you using .net 3.5?
Note that only 3.5+ supports that syntax.
Use String.Format:
var select = db.San_Imovel.Where(String.Format("Imovel_Id = {0}", 123)).Select("new(Imovel_Id)");

What is that 123 for? In order for this to compile, it will probably need to look like one of these:
var select = db.San_Imovel.Where("Imovel_Id = #0").Select("new(Imovel_Id)");
OR
var select = db.San_Imovel.Where("Imovel_Id = #0 AND SomethingElse = 123").Select("new(Imovel_Id)");

Related

What is the performance optimum (or even better coding practise) for writing this Linq query

I am new to linq so please excuse me if I am asking a very basic question:
paymentReceiptViewModel.EntityName = payment.CommitmentPayments.First().Commitment.Entity.GetEntityName();
paymentReceiptViewModel.HofItsId = payment.CommitmentPayments.First().Commitment.Entity.ResponsiblePerson.ItsId;
paymentReceiptViewModel.LocalId = payment.CommitmentPayments.First().Commitment.Entity.LocalEntityId;
paymentReceiptViewModel.EntityAddress = payment.CommitmentPayments.First().Commitment.Entity.Address.ToString();
This code is too repetitive and I am sure there is a better way of writing this.
Thanks in advance for looking this up.
Instead of executing query at each line, get commitment entity once:
var commitment = payment.CommitmentPayments.First().Commitment.Entity;
paymentReceiptViewModel.EntityName = commitment.GetEntityName();
paymentReceiptViewModel.HofItsId = commitment.ResponsiblePerson.ItsId;
paymentReceiptViewModel.LocalId = commitment.LocalEntityId;
paymentReceiptViewModel.EntityAddress = commitment.Address.ToString();
It depends a bit on what you are selecting to, you cannot select from one entity into another in Linq to Entities. If you are using LINQ to SQL and creating the paymentReceiptModel, you can do this.
var paymentReceiptModel = payment.CommitmentPayments.select(x=>new{
EntityName = x.Commitment.Entity.GetEntityName(),
HofItsId = x.Commitment.Entity.ResponsiblePerson.ItsId,
LocalId = x.Commitments.Entity.LocalEntityId,
EntityAddress = x.Commitment.Entity.Address
}).FirstOrDefault();
If you are using an already instantiated paymentReceiptModel and just need to assign properties then you are better looking to the solution by lazyberezovsky.
To get around the limitation in Linq to Entities, if that is what you are using, you could do this
var result = payment.CommitmentPayments.select(x=>x);
var paymentReceiptModel= result.select(x=>new
{
EntityName = x.Commitment.Entity.GetEntityName(),
HofItsId = x.Commitment.Entity.ResponsiblePerson.ItsId,
LocalId = x.Commitments.Entity.LocalEntityId,
EntityAddress = x.Commitment.Entity.Address
}).FirstOrDefault();
This essentially, makes the majority of your query Linq to Objects, only the first line is Linq to Entities

Dyamic Linq .Net 4 error 'userid' could not be resolved in the current scope or contex

I am trying to use Dynamic Linq library in my code, but it gives this error
'UserId' could not be resolved in the current scope or context. Make sure that all referenced variables are in scope, that required schemas are loaded, and that namespaces are referenced correctly. Near simple identifier, line 6, column 1
and here is my code
TestDB db = new TestDB();
string filter = "UserId == 15";
//var searchResult =
GridView1.DataSource = from x in db.SearchSummaries.Where(filter)
select x;
GridView1.DataBind();
Not so familiar with dynamic Linq but from your error message:
'UserId' could not be resolved in the current scope or context. Make
sure that all referenced variables are in scope, that required schemas
are loaded, and that namespaces are referenced correctly. Near simple
identifier, line 6, column 1
Please try this:
1.) Is the column UserId a Integer and not a String? Mabye you need to use:
string filter = "UserId='15'";
2.) Try to pass in the filter parameter as a second argument:
GridView1.DataSource = db.SearchSummaries.Where("UserId = #0", 15);
3.)
I don't know if you are able to run "regular" Linq queries, but if you are, try:
GridView1.DataSource = db.SearchSummaries.Where(search => search.UserId == 15);
GridView1.DataBind();
Try this:
TestDB db = new TestDB();
string filter = "xi => xi.UserId == 15";
//var searchResult =
GridView1.DataSource = from x in db.SearchSummaries.Where(filter)
select x;
GridView1.DataBind();
Or this:
TestDB db = new TestDB();
string filter = "UserId=15";
//var searchResult =
GridView1.DataSource = from x in db.SearchSummaries.Where(filter)
select x;
GridView1.DataBind();
EDIT: I realize this isn't dynamic linq...but it should work regardless as long as your data structure is correct. Could you post that?

Use enum in LinQ

need help
I have this enum which sets the PayClassNo to Direct and Indirect. I want to use this enum in my LinQ query.
Here's my scratch LinQ query:
var jDef = from jd in context.GetTable<RJVDefinition>()
select new PayrollJVDefinition
{
JVdefNo = jd.JVDefNo,
AccntCode = jd.AccntCode,
AccntDesc = jd.AccntDesc,
PayClass = enum.GetValue(jd.PayClassNo),
IsFixed = jd.IsFixed,
IsEmployee = jd.IsFixed,
IsAR = jd.IsAR,
CreatedByNo = jd.CreatedByNo,
CreatedDate = jd.CreatedDate,
ModifiedByNo = jd.ModifiedByNo,
ModifiedDate = jd.ModifiedDate
};
Need help because I'm not sure if this will work.
You could certainly do the translation in code, similar to your example (using Enum.Parse), but you don't need to. You can use the designer to set the object property type to an enumerated value. See this article for details.
You just need to parse the Enum just use something like
Enum.Parse(jb.PayClassNo, YourEnumType)

Subsonic Syntax Question (with GroupBy)

Is there a way to do this :
SubSonic.Where filter = new SubSonic.Where();
filter.ColumnName = Region.Columns.Region;
filter.Comparison = SubSonic.Comparison.IsNot;
filter.ParameterValue = null;
SubSonic.Aggregate orderBy = new SubSonic.Aggregate(Region.Columns.RegionName, SubSonic.AggregateFunction.GroupBy);
RegionCollection regions = new RegionCollection().Where(filter).GroupBy(groupBy).Load();
The "GroupBy" part in the last line doesn't compile... (I'm using SubSonic 2.1)
Just in case there isn't a reason you need the old Where construct:
SubSonic.Aggregate groupBy = new SubSonic.Aggregate(Region.Columns.RegionName, SubSonic.AggregateFunction.GroupBy);
RegionCollection regions = new SubSonic.Select(groupBy).From(Region.Schema).Where(Region.RegionColumn).IsNotNull().ExecuteAsCollection<RegionCollection>();
With Collections you can use OrderByAsc and OrderByDesc but they both only allow passing a string as a parameter. And the SubSonic.AggregateFunction.GroupByprobably isn't what you want.
Try this instead:
var result = new RegionCollection().OrderByAsc(Region.Columns.RegionName).Load();

Can Distinct be expressed using so-called embedded query rather than a method call

given the following code:
string[] colors = {"red","green","blue","red","green","blue"};
var distinctColors = (from c in colors select c).Distinct();
distinctColors.Dump();
Is it possible to fold the call .Distinct() into the embedded query syntax?
something like int T-SQL
select distinct color from TableofColors
C#'s query expression syntax doesn't include "distinct". VB's does, however - for example, from the MSDN docs for VB's Distinct clause:
// VB
Dim customerOrders = From cust In customers, ord In orders _
Where cust.CustomerID = ord.CustomerID _
Select cust.CompanyName, ord.OrderDate _
Distinct
The C# equivalent would have to explicitly call Distinct() in dot notation.
However, your example can still be simplified:
string[] colors = {"red","green","blue","red","green","blue"};
var distinctColors = colors.Distinct();
distinctColors.Dump();
Don't think you have to use query expressions to use LINQ :)
There's no distinct embedded query syntax in C# as far as I'm aware. This is as close as it gets:
var distinctColors = (from color in colors
select color).Distinct()
Query comprehension syntax does not support the Distinct method.
In your case, you could simply write colors.Distinct(); you're not doing anything with the query expression.
You can try this
var dis = from c in colors
group c by c;
foreach (var cVal in dis)
{
string s = cVal.Key;
}

Resources