I have List<Data> where Data is:
class Data
{
public int Id {get;set;}
public string Content {get;set;}
}
From Server I am getting following object List<ServerData> where ServerData:
class ServerData
{
int sId {get;set;}
Other stuff...
string sContent
}
Using LINQ, How I can find all matches that have same iD==sId, content==SContent?
just use a join ?
var matches = from data in listData
join serverData in listServerData
on new {id = data.Id, content = data.Content} equals
new {id = serverData.sId, content = serverData.sContent}
select new {
<whatever you need>
}
You can use this code:
IList<Data> data = //...
IList<ServerData> serverData = //...
IEnumerable<Data> matches = data.Where(d =>
serverData.Any(sd => sd.sId == d.Id &&
sd.sContent == d.Content));
Related
I am working on Web API. I am getting data from one database table:
DispatchData dta = new DispatchData();
using (SalesDataContext oSqlData4 = new SalesDataContext())
{
var result = (from x in oSqlData4.Finances
where (x.records.ID.Equals("12") ||
x.records.ID.Equals("123"))
where (x.Status == "Not Approved")
select x).ToList();
foreach (var item in result)
{
dta.data = new string[] { item.Order_ID.ToString(), item.ID.ToString() };
}
var json = JsonConvert.SerializeObject(dta);
return json;
}
public class DispatchData
{
public string[] data;
}
This code is returning only one record:
{ "data": ["2508", "4684"] }
I want each row in array like this
{"data":[ ["2508","4684"],["2223","1123"],....] }
Why not make return the result as strongly typed Model of List<DispatchData>:
Your DispatchData class:
public class DispatchData
{
public string Order_ID {get;set;}
public string ID {get;set;}
}
You can create a Root class to handle your JSON:
public class Root
{
public List<DispatchData> data=new List<DispatchData>();
}
And you can return from your query like this:
Root dta = new Root();
using (SalesDataContext oSqlData4 = new SalesDataContext())
{
dta.data = (from x in oSqlData4.Finances
where (x.records.ID.Equals("12") ||
x.records.ID.Equals("123"))
where (x.Status == "Not Approved")
select x).ToList();
var json = JsonConvert.SerializeObject(dta);
return json;
}
For the result you want, your class is defined wrongly
public class DispatchData
{
public string[][] data;
}
Then you can directly select the pair of IDs in an array, then nest them in another array, and assign it directly to dta.data
using (SalesDataContext oSqlData4 = new SalesDataContext())
{
var dta = new DispatchData() {
data = (from x in oSqlData4.Finances
where (x.records.ID.Equals("12") ||
x.records.ID.Equals("123"))
where (x.Status == "Not Approved")
select new[]{ x.Order_ID.ToString(), item.ID.ToString() }
).ToArray()
};
var json = JsonConvert.SerializeObject(dta);
return json;
}
Original data sheet:
SQL that can get the result you want:
select group_number,count(group_number) as group_count,receive_date
from hS_HZXX
where type = '1'
group by group_number,receive_date;
use ef core linq like this:
var hAATGroups = from p in dbContext.Set<HS_HZXX>()
where p.type == "1"
group p by new { Group_number = p.group_number, Sampling_date = p.sampling_date } into dto
select new DTO_HAATGroup
{
Group_number = dto.Key.Group_number,
HAAT_count = dto.Key.Group_number.Count(),
Sampling_date = dto.Key.Sampling_date.ToString("yyyy-MM-dd")
};
The DTO_HAATGroup:
public class DTO_HAATGroup
{
public string Group_number { get; set; }
public int HAAT_count { set; get; }
public string Sampling_date { get; set; }
}
The result of executing linq:
But I got the wrong result. . . Can you help me? How can I convert this SQL into a correct Linq statement.
I have solved this problem, the correct Linq writing is as follows:
var hAATGroups = from p in dbContext.Set<HS_HZXX>()
where p.type == "1"
group p by new { Group_number = p.group_number, Receive_date = p.receive_date } into dto
select new DTO_HAATGroup
{
Group_number = dto.Key.Group_number,
HAAT_count = dto.Count(),
Receive_date = dto.Key.Receive_date.ToString("yyyy-MM-dd")
};
I'm writing new api call for my android app, I want to retrieve data from dynamic table, I mean when user select "A" button from Andriod I want to retrieve data from "A" table and if "B" is click , retrieve data from "B" table. Someone help me to find the possible solution.
I want to replace with variable for "JBCTNRITEMs" from entities.JBCTNRITEMs (table-name)
var query = (from jbct in entities.JBCTNRITEMs
where jbid.Contains(jbct.jbid.ToString()) && boxid.Contains(jbct.TrackingNo.ToString())
select jbct).ToArray();
int id = 0;
if (query.Length > 0)
{
id = (query[0].id);
}
return id;
Here are the two different possibilities as an example
if (module.ToLower() == "module-a")
{
var imageinfo = (from jb in entities.TableA.AsEnumerable()
where scanID.Contains(jb.aid.ToString())
select jb).ToArray();
InsertGENIMAGE(userID, scanID, FilePath, imageinfo, "AIMAGE");
}
else if (module.ToLower() == "module-b")
{
var imageinfo = (from jb in entities.TableB.AsEnumerable()
where scanID.Contains(jb.bid.ToString())
select jb).ToArray();
InsertGENIMAGE(userID, scanID, FilePath, imageinfo, "BIMAGE");
}
Here, query stores what you are you trying to select. As long as you are trying to select same type or same anonymous type, it will work.
Here is a simple example:
class Test1
{
public int ID { get; set; }
public string Name { get; set; }
}
class Test2
{
public int ID { get; set; }
public string Name { get; set; }
}
var test1Lst = new List<Test1>
{
new Test1() { ID = 1, Name = "Jitendra" },
new Test1() { ID = 2, Name = "Jahnavi" }
};
var test2Lst = new List<Test2>
{
new Test2() { ID = 1, Name = "Aaditri" },
new Test2() { ID = 2, Name = "Pankaj" }
};
var test = false;
var query = test ? (from t in test1Lst select new { ID = t.ID, Name = t.Name }) : (from t in test2Lst select new { ID = t.ID, Name = t.Name });
// Put whatever condition you want to put here
query = query.Where(x => x.ID == 1);
foreach(var t1 in query)
{
Console.WriteLine(t1.ID + " " + t1.Name);
}
I guess in this case I would suggest to use a generic method :
private T GetMeTheFirstEntry<T>(Expression<Func<T, bool>> filter) where T : class
{
return entities.GetTable<T>().FirstOrDefault(filter);
}
The GetTable will allow you to interchange the tableA and tableB. You would call it the following way:
TableA tableA_entity = GetMeTheFirstEntry<TableA>(jb => scanID.Contains(jb.aid.ToString()));
TableB tableB_entity = GetMeTheFirstEntry<TableB>(jb => scanID.Contains(jb.bid.ToString()));
If the filtering was successfull, then the retrieved object will not be null and you can use it:
int a_id = tableA_entity.aid;
I have a model (sample below), and sample data with desired output..
I have also given two ways to populate model which will give desired output but for somereason,
looks like I am missing something....
Not able to figure out what is the issue here...
need inputs in correcting approach 1 or approach 2 or you can also suggest any other approach which will help populate model in below response..
models
class Emp
{
public int id {get;set;}
public int Name {get;set;}
public List<cardType> cardTypes {get;set;}
}
class cardType
{
public int name {get;set;}
public DateTime Expiry {get;set;}
}
sample data (Data is returned in 1 table only)
id Name cardTypeName exp
1 a Amex 1010
1 a City 2010
desired output
<Emp>
<ID>1</id>
<name>1</name>
<cardTypes>
<cardType>
<Name> Amex </Name>
<exp> 1010 </exp>
</cardType>
<cardType>
<Name> City </Name>
<exp> 2010 </exp>
</cardType>
<cardTypes>
</Emp>
approach 1
(dataTable.AsEnumerable()
.GroupBy(r => r.ItemArray[1])
.Select(grp => new Emp()
{
id = r.itemarray[1],
name = r.itemarray[1],
cardTypes = grp.Select(t => new cardType()
{
field 1,
field 2
}).ToList()
}));
approach 2
return (from DataRow dr in dataTable.Rows
select new Emp
{
id = "",
name= "",
cardTypes = dataTable.AsEnumerable()
.Select(x => new cardType
{
name = ""
exp = ""
}).ToList(),
});
try this
return dataTable.AsEnumerable()
.GroupBy(x => x.Id)
.Select(x => new
{
id = x.Key,
name = x.Key,
cardTypes = x.Select(t => new
{
name = t.Name,
exp = t.Exp
})
});
This should work for you considering you will change the Expiry field in cardType to int
var results =
dt.AsEnumerable()
.GroupBy(row => row.ItemArray[0])
.Select(rows => new Emp
{
id = rows.Key,
name = rows.Key,
cardTypes = rows.Select(row => new cardType {Name = row.ItemArray[2], Expiry = row.ItemArray[3]})
});
If you desire to have DateTime, then decide how to convert. For example:
cardTypes = rows.Select(row => new cardType {Name = row.ItemArray[2], Expiry = new DateTime(row.ItemArray[3],1,1)})
If you want to serialize to xml your models, you should mark your models with [Serializable] attribute and just use XmlSerializer.
[Serializable]
class Emp
{
public int id {get;set;}
public int Name {get;set;}
public List<cardType> cardTypes {get;set;}
}
[Serializable]
class cardType
{
public int name {get;set;}
public DateTime Expiry {get;set;}
}
After that you can use following code:
static Dictionary<int, Emp> ConvertToDict(DataTable dt)
{
Dictionary<int, Emp> emps = new Dictionary<int, Emp>();
foreach (var dr in dt.AsEnumerable())
{
var id = (int)dr["ID"];
var name = (string)dr["Name"];
var cardTypeName = (string)dr["CardTypeName"];
var exp = (int)dr["Exp"];
Emp emp;
var cardType = new CardType { Name = cardTypeName, Exp = exp };
if (emps.TryGetValue(id, out emp))
{
emp.CardTypes.Add(cardType);
}
else
{
emps.Add(id, new Emp { ID = id, Name = name, CardTypes = new List<CardType> { cardType } });
}
}
return emps;
}
static List<string> Serialize<T>(IEnumerable<T> entities) where T:new()
{
var ser = new XmlSerializer(typeof(T));
var serializedEntities = entities.Select(entity =>
{
using (var sw = new StringWriter())
{
ser.Serialize(sw, entity);
return sw.ToString();
}
}).ToList();
return serializedEntities;
}
I would like to make a query by using lambda select,
Like below:
public class Foo{
public int Id {get;set;}
public string Name {get;set;}
public string Surname {get;set;}
}
var list = new List<Foo>();
var temp = list.Select(x=> x("Name"),("Surname"));
The property name needs to be sent as a string,
I dont know how to use, I have given it for being a example.
is it possible?
Edit:
Foo list :
1 A B
2 C D
3 E F
4 G H
I don't know type of generic list, I have property name such as "Name", "Surname"
I want to be like below:
Result :
A B
C D
E F
G H
The following code snippet shows 2 cases. One filtering on the list, and another creating a new list of anonymous objects, having just Name and Surname.
List<Foo> list = new List<Foo>();
var newList = list.Select(x=> new {
AnyName1 = x.Name,
AnyName2 = x.Surname
});
var filteredList = list.Select(x => x.Name == "FilteredName" && x.Surname == "FilteredSurname");
var filteredListByLinq = from cust in list
where cust.Name == "Name" && cust.Surname == "Surname"
select cust;
var filteredByUsingReflection = list.Select(c => c.GetType().GetProperty("Name").GetValue(c, null));
Interface
If you have access to the types in question, and if you always want to access the same properties, the best option is to make the types implement the same interface:
public interface INamable
{
string Name { get; }
string Surname { get; }
}
public class Foo : INamable
{
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
}
This will preserve type safety and enable queries like this one:
public void ExtractUsingInterface<T>(IEnumerable<T> list) where T : INamable
{
var names = list.Select(o => new { Name = o.Name, Surname = o.Surname });
foreach (var n in names)
{
Console.WriteLine(n.Name + " " + n.Surname);
}
}
If, for some reason, you can't alter the original type, here are two more options.
Reflection
The first one is reflection. This is Mez's answer, i'll just rephrase it with an anonymous type like in the previous solution (not sure what you need exactly):
public void ExtractUsingReflection<T>(IEnumerable<T> list)
{
var names = list.Select(o => new
{
Name = GetStringValue(o, "Name"),
Surname = GetStringValue(o, "Surname")
});
foreach (var n in names)
{
Console.WriteLine(n.Name + " " + n.Surname);
}
}
private static string GetStringValue<T>(T obj, string propName)
{
return obj.GetType().GetProperty(propName).GetValue(obj, null) as string;
}
Dynamic
The second uses dynamic:
public void ExtractUsingDynamic(IEnumerable list)
{
var dynamicList = list.Cast<dynamic>();
var names = dynamicList.Select(d => new
{
Name = d.Name,
Surname = d.Surname
});
foreach (var n in names)
{
Console.WriteLine(n.Name + " " + n.Surname);
}
}
With that in place, the following code:
IEnumerable<INamable> list = new List<Foo>
{
new Foo() {Id = 1, Name = "FooName1", Surname = "FooSurname1"},
new Foo() {Id = 2, Name = "FooName2", Surname = "FooSurname2"}
};
ExtractUsingInterface(list);
// IEnumerable<object> list... will be fine for both solutions below
ExtractUsingReflection(list);
ExtractUsingDynamic(list);
will produce the expected output:
FooName1 FooSurname1
FooName2 FooSurname2
FooName1 FooSurname1
FooName2 FooSurname2
FooName1 FooSurname1
FooName2 FooSurname2
I'm sure you can fiddle with that and get to what you are trying to achieve.
var temp = list.Select(x => x.Name == "Name" && x.Surname == "Surname");
var temp = list.Select(x => new {Name = x.Name, Surname = x.Surname});