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;
Related
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 have 2 tables:
specs {specId, desc, createdby, lastupdatedby}
users {userid, username}
I want the below linq query need to be written in pure lambda expression
from spec in specs
from user in users.where(x => x.userId== spec.createdby).DefaultIfEmpty()
from updatedUser in users.where(x => x.userId== spec.lastupdatedbyby).DefaultIfEmpty()
select new {
spec = spec
user = user,
updatedUser = updatedUser
}
Please assist.
Data would be like say:
spec[{1, test, 1234, 2345},{2, test1, 1234, null}]
users[{1234, Allen},{2345, Dwayne}]
So the result should be
[{1, test, Allen, Dwayne}, {2, test1, Allen, null}]
Let's start with these classes:
class Specs {
public int specId { get; set; }
public string desc { get; set; }
public int createdby { get; set; }
public int lastupdatedby { get; set; }
}
class Users {
public int userId { get; set; }
public string username { get; set; }
}
class UpdatedUser {
public int userId {get; set;}
public string username { get; set; }
}
Now the Linq query, for convenience I have created some example data:
var specs = new Specs[]
{
new Specs{specId = 1, desc = "Spec1", createdby=1, lastupdatedby=1},
new Specs{specId = 2, desc = "Spec2", createdby=2, lastupdatedby=3},
new Specs{specId = 3, desc = "Spec3", createdby=3, lastupdatedby=1},
new Specs{specId = 4, desc = "Spec4", createdby=3, lastupdatedby=3},
};
var user = new Users[]
{
new Users{userId = 1, username = "User1"},
new Users{userId = 2, username = "User2"},
};
var updatedUser = new UpdatedUser[]
{
new UpdatedUser{userId = 1, username = "UpdatedUser1"},
new UpdatedUser{userId = 2, username = "UpdatedUser2"},
};
var result = specs
.GroupJoin(user,
s => s.createdby,
u => u.userId,
(s, u) => u.Select(x => new {spec = s, user = x})
.DefaultIfEmpty(new {spec = s, user = (Users)null}))
.SelectMany(g => g)
.GroupJoin(updatedUser,
firstJoin => firstJoin.spec.lastupdatedby,
uu => uu.userId,
(firstJoin, uu) =>
uu.Select(y => new {spec = firstJoin.spec, user = firstJoin.user, updatedUser = y})
.DefaultIfEmpty(new {spec = firstJoin.spec, user = firstJoin.user, updatedUser = (UpdatedUser) null}))
.SelectMany(g1 => g1)
.ToList();
The GroupJoin extension method help you obtain a tuple with all the elements of the starting table with a list of elements of the joined table.
Now if you enumerate the results:
result.ForEach(item => {
Console.WriteLine(item.spec.desc);
Console.WriteLine(item.user != null ? item.user.username : "NULL");
Console.WriteLine(item.updatedUser != null ? item.updatedUser.username : "NULL");
Console.WriteLine();
});
You obtain this:
Spec1
User1
UpdatedUser1
Spec2
User2
NULL
Spec3
NULL
UpdatedUser1
Spec4
NULL
NULL
You can try
var list = specs.Join(users,
s => s.lastupdatedby,
u => u.userid,
(s, u) => new { specs = s, users = u })
.Select(x => new {
specId = x.specs.specId,
desc = x.specs.desc,
createdby=x.specs.createdby,
username=x.users.username
}).ToString();
LEFT JOIN MULTIPLE TABLES
------------------------
create table Rama(rid int,name varchar(80),zip int);
create table Kris(kid int,rid int, Title varchar(80),zip int);
insert into Rama values(1,'Robert Rama' ,10001),
(2,'Roger Raju' ,10002),
(3,'Kevin Kali' ,10003),
(4,'Mark Mutu' ,10004)
insert into Kris values(0,0,'NP' ,10001),
(1,1,'VP' ,10001),
(2,2,'AVP',10002)
//Lambda expression
//Download https://www.linqpad.net/Download.aspx
//Create tables as given below and connect linqpad to your db
//select C# statement(s) on linqpad and run below
var v =
from r in Ramas
join k in Kris
on new { r.Rid, r.Zip } equals new { k.Rid, k.Zip }
into resultGroups
from k in resultGroups.DefaultIfEmpty()
select new { r.Rid, r.Name, k.Title };
v.Dump();
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});
I have a situation, where I get data from the database in such a way, that everything is stored in one-dimensional array.
For example:
User table: UserId, Name
Group table: GroupId, Name
UserGroup table: UserId, GroupId
As a result of joining these tables I obtain array of the following form:
result[0] = "1" // user id
result[1] = "John Doe" // user name
result[2] = "121" // group id
result[3] = "SomeGroup" // group name
result[4] = "1" // user id
result[5] = "John Doe" // user name
result[6] = "2135" // group id
result[7] = "SomeOtherGroup" // group name
I know it's not a good solution of keeping data, but these data are coming to me from some other piece of code which I am not allowed to change, so I have to deal with it.
My questions are:
Is this possible to use LINQ in order to parse this array and place data in my own objects (User class with Groups collection in it).
What is other best way to handle it if not by LINQ?
Pure linq Expression :
int i = 0;
var objects = result.GroupBy(x => Math.Floor(i++ / 4.0))
.Select(g => new { id =g.ElementAt(0), name = g.ElementAt(1), gId= g.ElementAt(2), group = g.ElementAt(3)})
.GroupBy(x=>new {x.id, x.name}, x=>new {x.gId, x.group})
.Select(y=>new {y.Key, groups = y.ToList()});
In the first GroupBy I group results in 4 elements subsets using a floor and a temporary variable.
Then The next Select put the resulting arrays in an anonymous type for better usability in the next steps.
The next GroupBy is used to group the entries by Employee. The Key will be the employee and the values will be the corresponding Groups.
Finaly the lase Selectis used to put the GroupByresult in a better shape. I choose to put the result in an other anonymous type but You could instantiate you custom objects here and put the values in the right fields using curly brace constructor.
If your logic depends on indexes LINQ is is rarely the right tool. It results in less readable, maintainable, efficient and robust code than with plain loops.
I would use something like following to create two dictionaries representing the many to many relation. Note the for-loop which increments by 4 on every iteration since that seems to be the user-group-"package":
var userIdGroups = new Dictionary<int, HashSet<Group>>();
var groupIdUsers = new Dictionary<int, HashSet<User>>();
for(int i = 0; i < result.Length; i += 4)
{
int id;
if(int.TryParse(result[i], out id))
{
string name = result.ElementAtOrDefault(i + 1);
if(name == null)
continue; // end, invalid data
User user = new User{ UserId = id, Name = name };
string groupID = result.ElementAtOrDefault(i + 2);
if(!int.TryParse(groupID, out id))
continue; // end, invalid data
name = result.ElementAtOrDefault(i + 3);
if(name == null)
continue; // end, invalid data
Group group = new Group{ GroupId = id, Name = name };
HashSet<Group> userGroups;
HashSet<User> groupUsers;
if (userIdGroups.TryGetValue(user.UserId, out userGroups))
userGroups.Add(group);
else
userIdGroups.Add(user.UserId, new HashSet<Group>{ group });
if (groupIdUsers.TryGetValue(group.GroupId, out groupUsers))
groupUsers.Add(user);
else
groupIdUsers.Add(group.GroupId, new HashSet<User> { user });
}
}
The result is:
the user-dictionary contains one user with two groups
the group-dictionary contains two groups which map to the same user
You have to override Equals and GetHashCode to compare the ID's:
class User
{
public int UserId { get; set; }
public string Name { get; set; }
public override bool Equals(object obj)
{
User u2 = obj as User;
if (u2 == null) return false;
return UserId == u2.UserId;
}
public override int GetHashCode()
{
return UserId;
}
}
class Group
{
public int GroupId { get; set; }
public string Name { get; set; }
public override bool Equals(object obj)
{
Group g2 = obj as Group;
if (g2 == null) return false;
return GroupId == g2.GroupId;
}
public override int GetHashCode()
{
return GroupId;
}
}
You can do it with the basic structures like loops:
void Main()
{
var result = new string[] {"1","John Doe","2","Joes Group","3","Jack Daniel","4","Jacks Group","5","Foo Bar","6","FooBar Group",};
List<Person> personList = new List<Person>();
List<Group> groupList = new List<Group>();
for(int i = 0; i < result.Length; i+=2)
{
i = i + 2;
//check if group does not already exist
groupList.Add(new Group() {Name = result[i+1]});
}
for(int i = 0; i < result.Length; i+=2)
{
//check if person exists.
//if person only add group to person personList.Where(x => x.Name ==result[i+1])....
personList.Add(new Person() { Id = int.Parse(result[i]),
Name = result[i+1],
Groups = new List<Group>()
{
groupList.FirstOrDefault (l => l.Name == result[i+3])
}
});
i = i+2;
}
personList.Dump();
}
public class Person
{
public Person()
{
Groups = new List<Group>();
}
public int Id { get; set; }
public string Name { get; set; }
public List<Group> Groups { get; set; }
}
public class Group
{
public string Name { get; set; }
}
// Define other methods and classes here
Output:
Please take advise: this code does not contain any validation logic, or duplicate checks. You'll have to imlpement this by yourself.
But before you implement something like this, I'd rather change the way you get your data delivered. this way you would deal with the root of your peroblems not with the symptoms.
i think no need to linq
//some class
public class Result
{
public string UserId {get;set;}
public string UserName {get;set;}
public string GroupId {get;set;}
public string GroupName {get;set;}
public string UserGroupUserId {get;set;}
public string UserGroupUserName {get;set;}
public string UserGroupId {get;set;}
public string UserGroupGroupId {get;set;}
}
// your array
private void Form1_Load(object sender, EventArgs e)
{
string[] result = new string[8];
result[0] = "1";
result[1] = "John Doe";
result[2] = "121";
result[3] = "SomeGroup";
result[4] = "1";
result[5] = "John Doe";
result[6] = "2135";
result[7] = "SomeOtherGroup";
Result r = CastResult(result);
}
// simple cast array to some type
public Result CastResult(string[] array)
{
return new Result() { UserId=array[0], UserName=array[1], GroupId=array[2], GroupName=array[3], UserGroupUserId=array[4], UserGroupUserName=array[5] , UserGroupId=array[6], UserGroupGroupId=array[7] };
}
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));