//Below mentioned class is created to understand the problem, while this is created through Linq2Sql.
public class JobAds
{
public int ID { get; set; }
public int EmployerRef { get; set;}
}
int? employerId = null;
var jobAdListing = JobAds.Where
( n => (!employerId.HasValue || n.EmployerRef == employerId.Value )).ToList();
The Issue is I'm getting "Nullable object must have a value." at the above line. After doing some debugging, I feel n.EmployerRef == employerId.Value is making some trouble, but unable to find anything good.
Just write liks this, you don't have to worry about the null values (since NULL == NULL equals false)
int? employerId = null;
var jobAdListing = tblCompanies.Where
(n => (n.fkUserID_responsible == employerId)).ToList();
Or you can keep your code and just remove the ".value"
var jobAdListing = JobAds.Where
( n => (!employerId.HasValue || n.EmployerRef == employerId)).ToList();
in my local playground a simmilar case works with this easiest approach:
using (UnitOfWork.Begin("LinqToSql"))
{
Guid? id1 = null;
Guid? id2 = this.personRepository.GetAll().First().FavouriteProjectId;
var all = this.personRepository.GetAll().Where(o => o.FavouriteProjectId == id1 || o.FavouriteProjectId == id2).ToArray();
}
for you, this should work too:
int? employerId = null;
int? employerType = null; /* OTHER Conditions */
var list = JobAds.Where(n => n.EmployerRef == employerId &&
n.EmployerTypeRef == employerType)).ToArray();
Related
I have two tables TA and TB. Both use the same PK (TB is a shadow table of TA). I need to identify all records from TA that are also in TB, but have one or more property values changed.
Sample code:
public class MyData
{
[Key]
public Guid PK { get; set; } = Guid.Empty;
public int Value1 { get; set; } = 0;
public int Value2 { get; set; } = 0;
}
What I need is something like find all records R from TA in TB where R(TA).PK == R(TB).PK && (R(TA).Value1 != R(TB).Value1 || R(TA).Value1 != R(TB).Value1)
However, I have no bloody clue how to write that down, neither as sql nor as Linq statement. I tried a lot of variants, but none was syntactically correct.
var result = ctx.TA.Where(a => ctx.TB.Any(b => a.PK == b.PK &&
(a.Value1 != b.Value1 || a.Value2 != b.Value2)));
Try the following query:
var query =
from ta in context.TableA
join tb in context.TableB on ta.PK equals tb.PK
where ta.Value1 != tb.Value1 || ta.Value2 != tb.Value2
select ta;
Hi I have a method which i am calling to get the list of email of users , i am returning that list and my calling method is using these emails , I want to get the program title as well to pass with the list how to achieve that.
public static List<string> GetAllStudents(int? year,int? program,int? module,int? block)
{
var res = (from s in std.Student_courses
join p in std.Programs
on s.Program_Id equals p.Id
join sc in std.Students
on s.Student_id equals sc.Student_Id
where s.Program_Id == program && s.Year_Id == year && s.Module_Id==module && s.Block_Id==block
select new
{
Email = sc.Student_Email,
Program=p.Program_Title
}).ToList();
List<string> EmailList = new List<string>();
foreach (var item in res)
{
EmailList.Add(item.Email);
}
return EmailList;
//var result = from userDistrict in std.Student_courses
// from district in std.Students
// where (userDistrict.Student_id == district.Student_Id)
// select district.Student_Email;
// return std.Student_courses.Where(x => x.Program_Id == program && x.Year_Id == year && x.Module_Id == module && x.Block_Id == block ).ToList();
}
Using new {} creates an anonymous type which cannot be passed to a method or returned out of the method scope (even if it's inside a list).
You are returning a list of string values. I recommend you change this to a list of a new class that contains both the email and the Program properties.
public class EmailInfo
{
public string Email { get; set; }
public string Program { get; set; }
}
You can then return this class from your method:
public static List<EmailInfo> GetAllStudents(int? year, int? program, int? module, int? block)
{
var results =
from s in std.Student_courses
join p in std.Programs on s.Program_Id equals p.Id
join sc in std.Students on s.Student_id equals sc.Student_Id
where s.Program_Id == program && s.Year_Id == year && s.Module_Id == module && s.Block_Id == block
select new EmailInfo
{
Email = sc.Student_Email,
Program = p.Program_Title
};
return results.ToList();
}
And use both values (as an example I've printed the values to the console):
var emails = GetAllStudents();
emails.ForEach(x => Console.WriteLine($"'{x.Email}', '{x.Program}'"));
This could print the following to the console:
'email1#domain.com', 'title 1'
'email2#domain.com', 'title 2'
I have documents with property _report_type, it supposed to contain a string "FTE", or "CAB".
In legacy document, it can be null or not exist at all (undefined), they are supposed to be "ContractorWorkReport".
My mapping:
public class Order : Document, IBaseEntity<string>
{
[JsonProperty(Order = 70, PropertyName = "orderData")]
public OrderData Data { get; set; }
}
public class OrderData
{
[JsonProperty(Order = 60, PropertyName = "_order_type")]
public OrderType? OrderType { get; set; }
}
[JsonConverter(typeof(StringEnumConverter))]
public enum OrderType
{
[EnumMember(Value = "TFE")]
ContractorWorkReport,
[EnumMember(Value = "CAB")]
BudgetElectricMeter
}
My query based on that :
var query = _client.CreateDocumentQuery<T>($"/dbs/{_databaseId}/colls/{CollectionId}");
if (filter.OrderType.Value == OrderType.ContractorWorkReport)
query = query.Where(o => o.Data.OrderType == null || !o.Data.OrderType.HasValue || o.Data.OrderType == filter.OrderType);
else
query = query.Where(o => o.Data.OrderType == filter.OrderType);
This query crashes because of the o.Data.OrderType == null, error message is :
Unable to cast object of type 'Microsoft.Azure.Documents.Sql.SqlNullLiteral' to type 'Microsoft.Azure.Documents.Sql.SqlNumberLiteral'.'
How can fix this? Right now, i do this, but it's dirty...
if (filter.OrderType.Value == OrderType.ContractorWorkReport)
query = query.Where(o => o.Data.OrderType != OrderType.BudgetElectricMeter);
else
query = query.Where(o => o.Data.OrderType == filter.OrderType);
Thanks!
First, I would recommend you use this for the first parameter in CreateDocumentQuery : UriFactory.CreateDocumentCollectionUri(databaseId, collectionId)
To answer your question, you are comparing an int to a null. o.Data.OrderType, being an enum, resolves to an int. You may want to compare that to the default enum value 0 or query over documents where o.Data.OrderType is not a key at all
I have a to add a specific requirement in a piece of code already implemented.
The data structure is something of this sort:
public class Module
{
public string Type;
public string ID;
public List<Point> Points = new List<Point>();
}
public class Point
{
public string Type;
public string Location;
public string Connection;
}
Originally LINQ was used to return all modules which certain characteristics
List<Module> miList = Modules.Where(m => m.Type != null
&& m.ID == "A"
&& m.Points.Where(t => t.Connection == ""
&& SimilarPoint(t.Type, x).ToList())
.Count() > 0)
.ToList();
with x an input to the function. The new requirement dictates that the modules returned shall all have points with Connection equal to "" and the same value in the Location field.
It seemed to me that the SelectMany could be used to this end, but I am not getting what I expected.
How should the function above be modified?
Thanks in advance
Not exactly sure what the SimilarPoint(t.Type, x) does here.
May be you should try something like this and find out if it works for you -
var resultSet = Modules.Where(m => !string.IsNullOrEmpty(m.Type) && m.ID.Equals("A"))
.Select(n =>
new Module {
Type=n.Type,
ID=n.ID,
Points= n.Points.Where(p => String.IsNullOrEmpty(p.Connection) && String.IsNullOrEmpty(p.Location)).ToList()
})
.ToList();
You said all the returned modules have the same Location, but that doesn't explain how you select which Location so I arbitrarily picked the first matching module's location:
var miQuery1 = Modules.Where(m => m.Type != null
&& m.ID == "A"
&& m.Points.Where(t => t.Connection == ""
&& SimilarPoint(t.Type, x).ToList()).Count() > 0)
.Where(m => m.Points.All(p => p.Connection == ""));
var miQuery2 = miQuery1.Where(m => m.Location == miQuery1.First().Location);
List<Module> miList = miQuery2.ToList();
How would I write the following SQL query in lambda-notation LINQ?
select 'myString', count(distinct val)
from myChildTable
where mytable_id in (
select id
from myTable
where col1_int = 6
and col2_int between 1 and 366
and col3_str = 'myString'
)
For reference, the two tables in question are:
create table myTable (
id int primary key identity,
col1_int int not null,
col2_int int not null,
col3_str varchar(1024)
)
create table myChildTable (
id int primary key identity,
mytable_id int not null foreign key references myTable(id),
val varbinary(13) not null
)
This could possibly be shortened but I find it easier to read if broken up:
// list ids from table
var ids = myTable.Where(x => x.Col1Int == 6 && x.Col2Int >= 1 && x.Col2Int <= 366 && x.Col3Str == "myString").Select(x => x.Id).ToList();
// use in subquery for values (non-distinct)
var vals = myChildTable.Where(x => ids.Contains(x.Id)).Select(x => x.Val).ToList();
// project to distinct dictionary of value, count
var dict = vals.Distinct().ToDictionary(x => x, x => vals.Count(y => y == x));
This seems to work using classes like these:
class ParentEntity
{
public int Id { get; set; }
public int Col1Int { get; set; }
public int Col2Int { get; set; }
public string Col3Str { get; set; }
public ParentEntity(int id, int col1Int, int col2Int, string col3Str)
{
Id = id;
Col1Int = col1Int;
Col2Int = col2Int;
Col3Str = col3Str;
}
}
class ChildEntity
{
public int Id { get; set; }
public int ParentEntityId { get; set; }
public string Val { get; set; }
public ChildEntity(int id, int parentEntityId, string val)
{
Id = id;
ParentEntityId = parentEntityId;
Val = val;
}
}
This query should to it:
from c in MyChildTables
where MyTables.Any (mt => mt.Col1_int == 6 && mt.Col2_int >= 1 &&
mt.Col2_int <= 366 && mt.Col3_str == "myString" && mt.Id == c.Id)
group c by true into g
select new
{
Col1 = "myString",
Col2 = g.Select (x => x.Val).Distinct().Count ()
}
Or if you rather have it in Lambda-notation:
MyChildTables
.Where (
c =>
MyTables
.Any (
mt =>
(((((mt.Col1_int == 6) && (mt.Col2_int >= 1)) && (mt.Col2_int <= 366)) && (mt.Col3_str == "myString")) && (mt.Id == c.Id))
)
)
.GroupBy (c => True)
.Select (
g =>
new
{
Col1 = "myString",
Col2 = g.Select (x => x.Val).Distinct ().Count ()
}
)