LINQ To SQL C# Update With Class - c#

I have users table with generated LINQ-class with followed structure:
class User {
int Id;
string Login;
string Password;
string Mail;
...
Now I need to update specified columns (for ex. only Login and Password) and because I don't want to overwrite other fields, my code looks like this:
public User UpdateUser(int userId, User newUser)
{
User user = (from u in _context.Users
where u.Id == userId
select u).FirstOrDefault();
if (newUser.Login != default(string)) user.Login = newUser.Login;
if (newUser.Mail != default(string)) user.Mail = newUser.Mail;
if (newUser.Password != default(string)) user.Password = newUser.Password;
...
_context.SubmitChanges();
return user;
}
And call it like this:
var user = new User { Password = "123" };
UpdateUser(123, user);
For each field I need to write IF statement and I thinking that I doing something wrong. Also because I am using comparsion with default(string) I cannot set empty values to rows.
Please, tell me, what is right way to do this?
P.S.: Please, sorry for my bad English.

You are misusing LINQ 2 SQL. You shouldn't even have a generic UpdateUser method because you don't need it. If you want to write a certain field of an entity, just do it:
var user = GetUser(userId);
user.Password = "123";
And you're done. When you have made all changes to the object model, call SubmitChanges at the end. It is not necessary to call it after each mutation.
You are using LINQ 2 SQL as a CRUD repository but it is not meant to be one. It is meant to give you a live object model that you can treat like normal C# objects. In the end you synchronize with the database by calling SubmitChanges.

This is possible just with SubmitChanges:
This gets the user:
var user=context.User.Where(m=>m.id == "xyz").FirstOrDefault();
This updates the above user:
user.Password = "xyz";
context.User.SubmitChanges();

I think you are looking into the wrong way for optimization. An update command on single column isn't much different than on every other column than PK. Your validation logics might take more time to process than your optimized update command.
However if it is always the password that needs to be updated, you can do it this way :
public User ChangePassword(int userId, string password)
{
var user = new User() { Id = userId };
_context.Users.Attach(user);
user.Password = password;
_context.SaveChanges();
return user;
}

Related

Return actual string value from LINQ SQLite query C#

Im currently creating a login system using SQLite using C# on Xamarin.ios. The issue Im having is that a send in a hashed password to the database which works fine. On the login side of it, I need to get the actually hashed value back so I can run a method which checks the returned value against the user inputted value.
The problem im having is that the query doesnt actually return a value as all and I dont actually understand what I get back from the query. I run FirstOrDefault to make sure I only get the email and password back whcih the user has enetered for their email. However, because I do not get a string value back, Im not sure on how ti put it into a method to check the hash value.
Hopefully this makes sense. This is the code which runs the query:
public void UserLogin()
{
string dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "PmApp.db3");
var connection = new SQLiteConnection(dbPath);
string loginEmail = loginEmailInput.Text;
string loginPass = loginPasswordInput.Text;
var emailExists = (from s in connection.Table<SQLiteTables.LoginInfo>()
where s.Email.Equals(loginEmail)
where s.Password.Equals(loginPass)
select s).FirstOrDefault();
Console.WriteLine(emailExists); //This is just to see what value gets returned
}
And this is the value that is returned:
2018-05-16 15:57:50.401 SQLite[15735:8043670] SQLite.SQLiteTables+LoginInfo
Hopefully somebody can help.
Jamie
var loginInfo = (from s in connection.Table<SQLiteTables.LoginInfo>()
where s.Email.Equals(loginEmail)
select s).FirstOrDefault();
if (loginInfo != null) {
var dbPass = loginInfo.Password;
if (hash(dbPass) == hash(loginPass) {
// hashed passwords match
}
}
you could also do the hash first
var hashedPass = hash(loginPass);
var loginInfo = (from s in connection.Table<SQLiteTables.LoginInfo>()
where s.Email.Equals(loginEmail)
where s.Password.Equals(hashedPass)
select s).FirstOrDefault();
if (loginInfo != null) {
// hashed passwords match
}
If you only need to return one column, try this :
var emailExists = (from s in connection.Table<SQLiteTables.LoginInfo>()
where s.Email.Equals(loginEmail)
where s.Password.Equals(loginPass)
select s.Email).FirstOrDefault();

MongoDb Search in Document's Collection returns only fully matched result - Why?

I'm trying to locate a user with a Username and a Password that match.
I have an office collection that each office document contains MANY users
var builder = Builders<MnOffice>.Filter;
var filter = builder.AnyEq(o => o.Users, new OfficeUser()
{
Username = username,
Password = password
});
var office = await Offices.Find(filter).FirstOrDefaultAsync().ConfigureAwait(false);
return office;
the above query returns null. although it should get the result back.
the OfficeUser class has three properties,
Username, Password, and Name.
Mongo forces me that all three properties will match in the query,
all I want is to have 2 properties matching (usename and password)
in order to get the result back,
How can accomplish that? no good documentation for that.
Thanks!
var filter = builder.ElemMatch(o => o.Users, user => user.Username == username && user.Password == password);
Solved that using ElemMatch, but still dont understand the logic behind the first attempt.

Table column make enum and return values as strings

I have an ASP.NET WebForms application with a (EF) database.
Basically the two tables I'm concerned with are Users and Roles.
In Roles there's: Id (pk), UserId (fk), Type : String - which contains either Admin, User, Moderator, Publisher, etc.
In Users there's: Id (pk), Email, NameFirst, NameLast, Password, Username.
In designer I connected Users with Roles so that in Roles -> UserId == Id of User.
And now, after creating a class that inherits from RoleProvider, in function GetRolesForUser(string username) I want to get the enum of all the roles of a user whose id is that of the username.
So for instance if I get a user Agon, I want to be able to get an enum of all his roles for later use and also return them as string[] in said method.
So for after hours of head-numbing attempts I've been getting consistent errors. Not sure where to go from here:
public override string[] GetRolesForUser(string username)
{
using (SMEntities db = new SMEntities())
{
User user = db.Users.First(x => x.Username == username);
}
//throw new NotImplementedException();
}
I'm not sure where enums come into play really on this one, but how about the following:
using (SMEntities db = new SMEntities())
{
User user = db.Users.First(x => x.Username == username);
return user.Roles.Select(r => r.Type).ToArray();
}

Get logged in user's id

How can I get the logged in user's UserId? I'm using the standard system generated AccountModel. I can get the username using:
User.Identity.Name
but I don't see the UserId field. I want to use the UserId as a foreign key for another table.
Try this:
using Microsoft.AspNet.Identity;
User.Identity.GetUserId();
That's how its done in the partial views for current MVC (MVC5/EF6/VS2013) templates.
Correct me if I'm wrong, because I've seen Aviatrix's answers a lot, but what happens if more than one user has the same name in the database?
I think you're looking for ProviderUserKey - Gets the user identifier from the membership data source for the user.
object id = Membership.GetUser().ProviderUserKey
Membership.GetUser() - Gets the information from the data source and updates the last-activity date/time stamp for the current logged-on membership user.
The best way to do so is to use the WebSecurty class
var memberId = WebSecurity.GetUserId(User.Identity.Name);
and don't forget to add [InitializeSimpleMembership] on top of your controller :)
Their are already very good answer but what i understood from your question is that you want to fetch data from database using id.so here is what you can do.
public List<ForeignkeyTable> RV()
{
var email = User.Identity.Name;
Usertable m = db.Uusertables.Where(x => x.user_Email == email).SingleOrDefault();
var id = m.user_Id;
var p = db.ForeignkeyTable.Where(x => x.user_fk_id == id).ToList();
return p;
}
This way you can return all the data from database of that id in foreignkey.

Updating a record using LINQ Context?

i am trying to update a user table with a single value update, but i can't figure out what i'm doing wrong. this is what i have:
public static void ApplyROB(string ROBread, string userName)
{
using (SERTEntities ctx = CommonSERT.GetSERTContext())
{
// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
// Audit of the transfer
datUser trUser = new datUserRole();
trUser.ROB = ROBread;
trUser.AccountName = userName;
// Persist update to DB
ctx.SaveChanges();
}
}
am i way off? nothing happens when i click on the update.
how do i say, where username = username? did i do it right?
basically in need a simple:
update datUser set ROB = "Y" where AccountName= "myusername"
it's turning out to be a bit more complicated in LINQ using Context
please help.
You're not adding your new entity to the context, thus when you save, the context is unaware of any changes. You need something like...
ctx.datUserRoles.Add(datUserRole)
To do an update, you need to retreive an entity from the context, make changes to it, then save... so:
var entity=ctx.datUserRoles.SingleOrDefault(dur=>dur.AccountName==someUserName);
if(entity!=null)
{
entity.someProp=someVal;
ctx.SaveChanges();
}
else
{
throw new UnexpectedOperationException(); //or however you want to fail
}
If you need an update. Maybe something like this:
public static void ApplyROB(string ROBread, string userName)
{
using (SERTEntities ctx = CommonSERT.GetSERTContext())
{
var trUser= ctx.datUserRole.Where(a=>a.AccountName==userName)
.FirstOrDefault();
if(trUser!=null)
{
trUser.ROB = ROBread;
ctx.SaveChanges();
}
}
}
If you are sure that you will always have something to update you can use First(). Then you do not need to check if the trUser is null
spender is correct in a sense, incorrect in another: you want to update an existing record.
For that you'll need to select the record first, for instance:
var user =
(from u in ctx.datUserRoles
where u.AccountName == "accountname"
select u).FirstOrDefault();
Where accountname is a valid thing of the same type - that doesn't matter, since you can select it how you want, you can touch that up to meet your criteria. Then once you have the item do the stuff:
if (user != null) {
user.ROB = ROBread;
ctx.SaveChanges();
}

Categories

Resources