Return Row to Array - c#

I'm work with C# and linq, and am trying to return some results from a table in a string, or array.
I am able to create a query, look up the row, but when I try to return column values, I get empty array of my table column names as my string.
Here is my result:
SELECT [t0].[UserID], [t0].[First], [t0].[Last], [t0].[Username], [t0].[Password], [t0].[Employee], [t0].[City], [t0].[Branch], [t0].[UserPoints], [t0].[CurrentPoints], [t0].[LastOnline], [t0].[Status] FROM [dbo].[mrobUsers] AS [t0] WHERE [t0].[Username] = #p0
Here is my Linq query:
public string GetUserInfo(string username)
{
try
{
using (UserDataDataContext db = new UserDataDataContext())
{
var getInfo = (from row
in db.mrobUsers
where row.Username == username
select row).ToString();
return getInfo;
// I've debugged up to here, and my user name is passed into this
}
}
catch (Exception e)
{
return MySerializer.Serialize(false);
}
}
My ideal result would be:
1,Mark,Rob,mrob88, password....etc

You could try this one:
// You should change the return type of your method, if you want to return an array of
// strings.
public string[] GetUserInfo(string username)
{
try
{
using (UserDataDataContext db = new UserDataDataContext())
{
// Get the user's info.
var userInfo = (from row in db.mrobUsers
where row.Username == username
select row).SingleOrDefault();
// If the user's info found return the corresponding values.
if(userInfo!=null)
{
var t = typeof(userInfo);
List<string> values = new List<string>();
foreach(var prop in t.GetProperties())
{
values.Add(prop.GetValue(userInfo, null);
}
return values.ToArray();
}
else // the user's info not found and return an empty array.
{
return new string[] { };
}
// I've debugged up to here, and my user name is passed into this
}
}
catch (Exception e)
{
return MySerializer.Serialize(false);
}
}
}
However, I suggest you not follow this approach. I think it would be better, if you declare a class with properties the values that you want to retrieve, like below:
public class UserInfo
{
public int UserId { get; set; }
public string First { get; set; }
public string Last { get; set; }
// the same way you will declare the rest of your properties.
}
Then you could change your method to the following one:
public UserInfo GetUserInfo(string username)
{
try
{
using (UserDataDataContext db = new UserDataDataContext())
{
// Get the user's info.
var userInfo = (from row in db.mrobUsers
where row.Username == username
select new UserInfo
{
UserId = row.UserId,
First = row.First
Last = row.Last
}).SingleOrDefault();
return userInfo;
}
catch (Exception e)
{
return MySerializer.Serialize(false);
}
}
}

Related

while loop Return Null Exception from SQL Table

i wrote a while loop to find each person file number from a table and add it inside another class array but for some reason, it returns an Object reference not set to an instance of an object ERROR. Here is My Class
public class Person
{
public string IDENTITY { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public class Exam[] Exams;
public string Data { get; set; }
}
public class Exam
{
public string IDENTITY
public string Name
public int Pass_Score
public int Score
public string Grade
}
and I have a table for person and table for Exam, My Goal is to Connect each person with all the exams he has in the exam table to return it as XML file.
[ResponseType(typeof(Person))]
public async Task<IHttpActionResult> GetPerson(string id)
{
Person p = await db.Person.FindAsync(id);
int count = db.Exam.Count();
Exam fS = new Exam();
int i = 0;
while (i < count) {
if (fS.IDENTITY.Equals(p.IDENTITY)) {
Exam e = new Exam();
e.IDENTITY = fS.IDENTITY;
e.Name= fS.Name;
e.Pass_Score = fS.Pass_Score ;
e.Grade= fS.Grade;
e.Score = fS.Score ;
i++;
};
}
if (p== null)
{
return NotFound();
}
return Ok(p);
}
My Guess's the Error Comes from inside the While loop?
#Dour High Arch: This is not a query about the null ref. but where it is ocurring.
step through your code, in the GetPerson function, is p populated? Which one of the return functions is it getting to? The return NotFound() or Ok(p)?
You are creating a new exam FS then you loop through all of the exams without assigning FS or e to anything, your if statement here if (fS.IDENTITY.Equals(p.IDENTITY)) { is always false and indeed it just ads the client details to an exam which is then forgotten.
There are a lot of issues with this code:
you are not using constructors inside your objects (getting null refs)
You are looking for FS.Identity = p.Identity without setting FS or it's id. (possible null ref)
You are not actually retrieving any exams from the database.
Exam e inside the loop never gets put into anything.
Using a while loop when a foreach would do (minor readability)
No Try/Catch being used
Way overcomplicated approach.
Below is a rough example of how I would approach it:
[ResponseType(typeof(Person))]
public async Task<IHttpActionResult> GetPerson(string id)
{
Person p = new Person();
try {
p = await db.Person.FindAsync(id);
if(p == null) {
throw new Exception("Person " + id + " not found.");
}
var exams = db.Exam.FindAsync(p.IDENTITY);
if(exams != null) {
p.Exams = new Exam[exams.Count()];
p.Exams = exams.ToArray();
}
}
catch(Exception e) {
//log exception here, is it just a person not found or somehting else?
return NotFound();
}
return OK(p);
}
A foreach loop example, the above is far better, and this method acheives nothing new:
var output = new List<Exam>();
var exams = db.getallexams();
foreach(var item in exams) {
output.Add(item);
}
p.Exams = output.ToArray();

Search method for different columns

I have Form with ComboBox and TextBox. The first contains the column names, and the second contains the text to search for. As a source, ComboBox takes ListTypeSearch from ItemSearch elements. The Search() method is called in the processing of pressing the Search button.
If give the column a name like this, nothing will be found
EF.Functions.Like(item.Value, ...); // Value = "FullName"
If specify a column from the model, the search works
EF.Functions.Like(w.FullName, ...);
Is it possible to replace the column that should be searched within the same Search() method?
ListTypeSearch.Add(new ItemSearch { Value = "FullName", Display = "some text" });
ListTypeSearch.Add(new ItemSearch { Value = "PassportSeries", Display = "some text" });
ListTypeSearch.Add(new ItemSearch { Value = "PassportNumber", Display = "some text" });
public class ItemSearch
{
public string Value { get; set; }
public string Display { get; set; }
}
internal List<WorkerTableRow> Search(ItemSearch item, string text)
{
try
{
Found = new List<WorkerTableRow>();
using (ModelContext model = new ModelContext())
{
Found = (from w in model.Workers
where EF.Functions.Like(w.FullName, // this code
String.Format("%{0}%", text))
select new WorkerTableRow
{
...
})
.ToList();
}
}
catch (Exception ex) { ... }
return Found;
}
Update
Now I did like this. It's works. Can this be simplified?
where EF.Functions.Like(w.GetProperty(item.Value),
String.Format("%{0}%", text))
public partial class Workers
{
...
public string FullName { get; set; }
public string PassportSeries { get; set; }
public string PassportNumber { get; set; }
public string GetProperty(string name)
{
switch (name)
{
case "FullName":
return FullName;
case "PassportSeries":
return PassportSeries;
case "PassportNumber":
return PassportNumber;
default:
return string.Empty;
}
}
}
According other answer. If uses Like(w.GetProperty(item.Value), ...), the request is executed on the client, not on the server. To send the entire request to the server, you can do the following:
List<WorkerTableRow> Search(ItemSearch item, string text)
{
string pattern = string.Format("%{0}%", text);
using (var model = new ModelContext())
{
IQueryable<Worker> query = model.Workers;
if (item.Value == "FullName")
query = query.Where(w => EF.Functions.Like(w.FullName, pattern));
if (item.Value == "PassportSeries")
query = query.Where(w => EF.Functions.Like(w.PassportSeries, pattern));
if (item.Value == "PassportNumber")
query = query.Where(w => EF.Functions.Like(w.PassportNumber, pattern));
return query.Select(w => new WorkerTableRow { ... }).ToList();
}
}

SQLiteConnection Query

I'm trying to select data from Database using SQLiteConnection. It's an UWP application.
public class ResumeModel
{
public List<User> Users { get; set; } = new List<User>();
public ResumeModel()
{
using (var connection = new SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), App.path))
{
try
{
object query = connection.Query<User>("Select * From User", null);
if(query != null)
{
Users = (List <User>) query;
}
} catch(Exception ex)
{
Debug.Write(ex.ToString());
}
}
}
}
I'm getting the exception: "Object reference not set to an instance of an object"
Here is my User class:
public class User
{
[SQLite.Net.Attributes.PrimaryKey, SQLite.Net.Attributes.AutoIncrement]
public int userID { get; set; }
public String username { get; set; }
public User()
{ }
public User(int userID, string name)
{
this.userID = userID;
this.username = name;
}
}
Does anyone know what I'm doing wrong?
Thanks
You are not bringing single User. You are selecting "*".
Also you are not passing any parameters. So Instead of Null remove that altogether.
I also see you are checking if query != null you don't have to do that. If there is no data, you will receive count as 0
So your query should be
List<User> query = connection.Query<User>("Select * From User");
Try storing your userID entries and your username entries into seperate, but index related lists. Then loop through and initialize a User object for each of the entries of these two lists as your constructor parameters.
List<int> userIDs = connection.Query<int>("Select userID From User order by userIDs");
List<string> userNames = connection.Query<string>("Select userName From User order by userIDs");
List<User> Users = new List<User>();
for (int i = 0; i < userIDs.Count(); i++)
{
User addition = new User(userIDs[i], userNames[i]);
Users.add(addition);
}
The order by clause is to ensure the indexes of the two queries match.

how to get two table combine record using entity framework with linq c#?

I want to get two table combine data using linq c# lambda expression and get fix number of column get in the list.
I have try this code but I don't know how to write query in linq lambda expression.
this is my method:
public ActionResult GetUserList(string searchRequest)
{
List<User> userList = new List<User>();
if (searchRequest != null)
{
if (searchRequest == "All")
{
// here i want to write select query but how i don't know
userList = db.user.ToList();
}
else if (searchRequest == "Flight")
{
userList = db.user
.Where(t => t.type_id == (int)ServiceTypeEnum.Flight)
.ToList();
}
}
return Json(new { data = userList });
}
any one have the idea about this query then please let me know how can do.
The issue that you will experience with lambdas where you select specific fields is that the result is normally an anonymous type. Anonymous types from two different queries cannot easily be joined together in a list because the compiler cannot verify the structure or equality of the types.
There are other ways around this...
The best practice approach is to create a formal type definition and use that so that you can manipulate your objects outside of your lambda expressions. Note here that I have assumed a simple example structure that is a sub-set of user:
public ActionResult GetUserList(string searchRequest)
{
try
{
List<UserSearchResult> UserList = new List<UserSearchResult>();
if (searchRequest != null)
{
if (searchRequest == "All")
{
UserList.AddRange(db.user.Select(u => new UserSearchResult { Title = u.Title, FirstName = u.Firstname, LastName = u.Lastname })); // here i want to write select query but how i don't know
}
else if (searchRequest == "Flight")
{
UserList.AddRange(db.user.Where(t => t.type_id == (int)ServiceTypeEnum.Flight)
.Select(u => new UserSearchResult { Title = u.Title, FirstName = u.Firstname, LastName = u.Lastname }));
}
}
return Json(new { data = UserList });
}
catch (Exception ex)
{
throw;
}
return Json(null);
}
public class UserSearchResult
{
public string Title { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Because we have explicitly cast the result of our selection of specific fields to a formal type, we can now use that type in operations outside of your queries and can even manipulate the values.
Define UserDto class for columns that you want select
public class UserDto
{
public int Id{get;set;}
public int Name{get;set;}
//Other Properties
}
Then change your code to following
public ActionResult GetUserList(string searchRequest)
{
try
{
if (searchRequest != null)
{
IQueryable<User> query;
if (searchRequest == "All")
{
query = db.user.AsQueryable(); // here i want to write select query but how i don't know
}
else if (searchRequest == "Flight")
{
UserList = db.user.Where(t => t.type_id == (int)ServiceTypeEnum.Flight);
}
if(query != null)
{
var list = query.Select(e=> new UserDto
{
Id = e.Id,
Name = e.Name
//Other properties
}).ToList();
return Json(new { data = list });
}
}
}
catch (Exception ex)
{
throw;
}
return Json(null);
}
I think the local variable is holding you back. Just return the result you want.
public ActionResult GetUserList(string searchRequest)
{
if (searchRequest == "All")
{
var users = db.user
.Select(user => new {user.Name, user.Address.ZipCode})
.ToList();
return ToJson(users);
}
else if (searchRequest == "Flight")
{
List<User> users = db.user
.Where(t => t.type_id == (int)ServiceTypeEnum.Flight)
.ToList();
return ToJson(users);
}
return ToJson(new List<User>());
}
private ActionResult ToJson<T>(T list)
{
return Json(new { data = list });
}

Return multiple items from a foreach loop

I would like to ask how I can return just the for each loop
current im getting a not all code paths return a value .
public Config getConfigSingle(string CID, string name)
{
var raw = db.ap_GetInfo(CID, name);
foreach (var item in raw.ToList())
{
return new Config
{
Name = item.Name.ToString(),
Value = item.Value.ToString(),
};
}
}
public partial class ClubConfig
{
public string Name { get; set; }
public string Value { get; set; }
}
Thanks M
You can use yield:
public IEnumerable<Config> getConfigSingle(string CID, string name)
{
var raw = db.ap_GetInfo(CID, name);
foreach (var item in raw.ToList())
{
yield return new Config
{
Name = item.Name.ToString(),
Value = item.Value.ToString(),
};
}
}
you can use LINQ to build your object to return:
public List<Config> getConfigSingle(string CID, string name)
{
var raw = db.ap_GetInfo(CID, name);
return raw.Select(r => new Config
{
Name = r.Name.ToString(),
Value = r.Value.ToString()
}).ToList();
}
You must return a value for each code path. If you collectio in the foreach is empty, the method would return nothing. Add a return null at the end.
public Config getConfigSingle(string CID, string name)
{
var raw = db.ap_GetInfo(CID, name);
foreach (var item in raw.ToList())
{
return new Config
{
Name = item.Name.ToString(),
Value = item.Value.ToString(),
};
}
return null;
}

Categories