How to update only one column value in database using Entity Framework? - entity-framework

I have a table with columns username, password. Data can be updated by admin for the table.
Now I want to add a new column named IsAgree (as a flag), it need to set when user logs in for the first time. But while setting data, it should not affect other column data, I will only send usename and Isagree flag as an object.
flgDetail = { usename:"vis" Isallowed:True }
[Route("api/TermsAndCondition/setflag")]
public IHttpActionResult post(FlagDetails FlagDetail)
{
var user = _context.table.Where(s => s.UserName == flagDetail.UserName);
}
Should I use post or put?
How can I update only one column?
And it should not affect other columns.

you can use either post or put.It's not a problem.You can update it as shown below.
[Route("api/TermsAndCondition/setflag")]
public IHttpActionResult post(FlagDetails flagDetail)
{
var user = _context.table.Where(s => s.UserName == flagDetail.UserName);
user.IsAgree =flagDetail.Isallowed;
_context.SaveChanges()
}

Related

Yii2: How to do a simple join query?

I am learning how to do simple queries using the Yii2 framework. I use PostgreSQL.
I am trying to join two tables and get the data from both tables with a where condition.
The tables are called Admins and Persons.
The join use field called idadm.
The condition is idadm = 33. This works great but the result has data only from the Admins table and I need data from the other table.
Here is my example:
$query = \app\models\Admins::find()
->select('*')
->leftJoin('persons', 'persons.idadm = admins.idadm')
->where(['admins.idadm' => 33])
->with('persons')
->all();
I am following the Yii2 official guide: http://www.yiiframework.com/doc-2.0/guide-db-active-record.html
Update: Here I show the updated code that doesn't solve de problem:
You need to write all column name in select().
$query = \app\models\Admins::find()
->select('admin.*,persons.*') // make sure same column name not there in both table
->leftJoin('persons', 'persons.idadm = admins.idadm')
->where(['admins.idadm' => 33])
->with('persons')
->all();
And also you need to define person table attributes in Admin model.
Second way is get records as array,so you dont need to define attributes in Admin model.
$query = \app\models\Admins::find()
->select('admin.*,persons.*') // make sure same column name not there in both table
->leftJoin('persons', 'persons.idadm = admins.idadm')
->where(['admins.idadm' => 33])
->with('persons')
->asArray()
->all();
Ensure that active record has required relations, e.g. something like follows:
class Admins extends \yii\db\ActiveRecord {
public function table() {
return "admins";
}
public function getPersons()
{
return $this->hasMany(Person::className(), ['idadm' => 'idadm']);
}
}
class Person extends \yii\db\ActiveRecord {
public function table() {
return "persons";
}
}
Then use joinWith to build query:
$query = Admins::find()
->joinWith('persons')
->limit(1);
$result = $query->createCommand()->getSql();
echo $result;
Here is produced query:
SELECT `admins`.* FROM `admins`
LEFT JOIN `person` ON `admins`.`idadm` = `person`.`idadm` LIMIT 1

Insert/Update data to Many to Many Entity Framework . How do I do it?

My context is =>
Using this model via Entity Framework code 1st,
data table in database becomes =>
1) User Table
2) Role Table
3) UserRole Table - A new linked table created automatically
Model for User is =>
Model for Role is =>
and my O Data query for inserting record for single User/Role table working properly
Now, what query should I write, when I want to Insert record to UserRole table
can someone have any idea
// Fetch the user.
var user = await metadataManagentClient.For<User>().FirstOrDefaultAsync(x => x.Name == "Test");
// If you want to add a new role.
var newRole = new Role()
{
Name = "My new role"
};
user.Roles.Add(newRole); // Adds new role to user.
// If you want to add an existing role
var existingRole = await metadataManagentClient.For<Role>().FirstOrDefaultAsync(x => x.Name == "My Existing Role");
user.Roles.Add(existingRole); // Adds existing role to user.
// Save changes.
metadataManagentClient.SaveChanges();
Or
await metadataManagentClient.SaveChangesAsync();
You might want to set ID as well. But watch out for new Guid() since it generates an empty guid. What you probably want (if you're not using IDENTITY) is Guid.NewGuid().

Entity Framework Interceptor to set Id field of patricular entities

In my current project i am working with the database which has very strange table structure (All Id Fields in most tables are marked as not nullable and primary while there is not auto increment increment enabled for them those Id fields need to be unique as well).
unfortunately there is not way i can modify DB so i find another why to handle my problem.
I have no issues while querying for data but during insert What i want to do is,
To get max Id from table where entity is about to be inserted and increment it by one or even better use SSELECT max(id) pattern during insert.
I was hoping to use Interceptor inside EF to achieve this but is looks too difficult for me now and all i managed to do is to identify if this is insert command or not.
Can someone help me through my way on this problem? how can i achieve this and set ID s during insert either by selecting max ID or using SELECT max(id)
public void TreeCreated(DbCommandTreeInterceptionContext context)
{
if (context.OriginalResult.CommandTreeKind != DbCommandTreeKind.Insert && context.OriginalResult.DataSpace != DataSpace.CSSpace) return;
{
var insertCommand = context.Result as DbInsertCommandTree;
var property = insertCommand?.Target.VariableType.EdmType.MetadataProperties.FirstOrDefault(x => x.Name == "TableName");
if (property == null) return;
var tbaleName = property?.Value as ReadOnlyCollection<EdmMember>;
var variableReference = insertCommand.Target.VariableType.Variable(insertCommand.Target.VariableName);
var tenantProperty = variableReference.Property("ID");
var tenantSetClause = DbExpressionBuilder.SetClause(tenantProperty, DbExpression.FromString("(SELECT MAX(ID) FROM SOMEHOWGETTABLENAME)"));
var filteredSetClauses = insertCommand.SetClauses.Cast<DbSetClause>().Where(sc => ((DbPropertyExpression)sc.Property).Property.Name != "ID");
var finalSetClauses = new ReadOnlyCollection<DbModificationClause>(new List<DbModificationClause>(filteredSetClauses) { tenantSetClause });
var newInsertCommand = new DbInsertCommandTree(
insertCommand.MetadataWorkspace,
insertCommand.DataSpace,
insertCommand.Target,
finalSetClauses,
insertCommand.Returning);
context.Result = newInsertCommand;
}
}
Unfortunately that concept of Interceptor is a little bit new for me and i do not understand it completely.
UPDATE
I manage to dynamically build that expression so that ID field is now included in insert statement, but the problem here is that I can not use SQL query inside it. whenever i try to use this it always results in some wrong SQL query so is there anyway i tweak insert statement so that this SELECT MAX(ID) FROM TABLE_NAME is executed during insert?
Get the next id from the context, and then set the parameter of the insert command accordingly.
void NonQueryExecuting(DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
{
var context = interceptionContext.DbContexts.First() as WhateverYourEntityContainerNameIs;
// get the next id from the database using the context
var theNextId = (from foo in context...)
// update the parameter on the command
command.Parameters["YourIdField"].Value = theNextId;
}
Just bear in mind this is not terribly thread safe; if two users update the same table at exactly the same time, they could theoretically get the same id. This is going to be a problem no matter what update method you use if you manage keys in the application instead of the database. But it looks like that decision is out of your hands.
If this is going to be a problem, you might have to do something more drastic like alter the command.CommandText to replace the value in the values clause with a subquery, for example change
insert into ... values (#YourIdField, ...)
to
insert into ... values ((select max(id) from...), ...)

Prevent fetching reference table values while using entityframework

I am using EntityFramework in my Apllication. If I want to fetch one table value means that will return values with all the referenced table values. It takes time to fetch all the table values. If I need one specified reference table values means
How do I Prevent fetching other reference table values?
If you want to extract single table record without reference tables so you need to define LazyLoadingEnabled false in your DBContext class.
Example your database name is EmpReview
public class UserDataLayerContext : DbContext
{
public UserDataLayerContext()
: base("name=EmpReview")
{
this.Configuration.LazyLoadingEnabled = false;
}
So all the DBSet classes which in UserDataLayerContext filter time only get the single table record without any reference class.
Using this.Configuration.LazyLoadingEnabled = false; none of return reference table calss but in that you need to get single reference table check below example,
Suppose one table class is UserMaster and it is link to GroupMaster master
So
return context.UserMasters.Include("GroupMaster").Where(x => (x.UserID == id) && (x.IsActive ==
true)).ToList();
In that case you get all the usermaster record with group master table.
And
return context.UserMasters.Where(x => (x.UserID == id) && (x.IsActive == true)).ToList();
above case you get all the record of usermaster with out group master table.

Query regarding trigger?

I am having following requirement:
1) To get list of all the users for whome profile has been changed.
2) Then query on FRUP (It is a custom object) to retrieve all the records which are associated with the user whose profile is changed.(FRUP object will contain the list of all the records created by all the users on all the objects say Account, Opportunity)
3) Update FRUP.
For achieving this I wrote one trigger through which i am able to fetch list of all the users whose profile has changed which is as follows:
Trigger UserProfileTrigger on User (before update) {
List<User> usr = new List<User>();
Map<String,String> userMap = new Map<String,String>();
for(User u: Trigger.new){
//Create an old and new map so that we can compare values
User oldOpp = Trigger.oldMap.get(u.ID);
User newOpp = Trigger.newMap.get(u.ID);
//Retrieve the old and new profile
string oldProfileId = oldOpp.profileId;
string newProfileId = newOpp.profileId;
//If the fields are different, the profile has changed
if(oldProfileId != newProfileId){
System.debug('Old:'+oldProfileId);
System.debug('New :'+newProfileId);
usr.add(u);
System.debug('User :'+usr);
}
}
}
Also Following are the fields on custom object FRUP:
1)Owner
2)Name
3)Record ID
4)Folder ID
5)Created By
6)Last Modified By
any help/suggestions??
I'm not sure what field on the FRUP references the user Id it relates to, but you can loop through the FRUP object with something like this:
List<FRUP> frupToUpdate = new List<FRUP>();
for (FRUP f : [
Select
OwnerId,
Name, //etc.
UserId //the field that references the user Id
from FRUP
where userId = : usr]) {
//update field on FRUP, e.g. f.Name = 'New Name';
frupToUpdate.add(f);
}
This selects the FRUP records that relate to the users with changed profiles. It then updates a field on the record and adds the record to a list for updating. Note that this should be after your loop for(User u: Trigger.new). Then update the FRUP records that have changed:
update frupToUpdate;