So, I'm trying to update rows where LOGIN IS NULL and ID = 1. If there are no rows with these parameters then add new row. I use attach to make that in 1-2 queries so I'm trying to avoid SELECT first and then update.
Problem in NULL value. EF simply ignores LOGIN since it has null value, however I need to find only rows where LOGIN IS NULL. Can I solve that problem without additional SELECT query?
My code:
using (var db = new EntityContext())
{
var ent = new Entity { ID = 1, LOGIN = null };
db.Entities.Attach(ent);
ent.LOGIN = "Whatever";
ent.EMAIL = "Whatever";
int count = db.SaveChanges();
if (count == 0)
{
var clone_ent = new Entity { LOGIN = "Whatever", PASS = "Whatever" };
db.Entities.Add(clone_ent);
db.SaveChanges();
}
}
SQL analog:
UPDATE Entities SET LOGIN = #LOGIN, EMAIL = #EMAIL
WHERE ID = 1 AND LOGIN IS NULL
IF ##ROWCOUNT = 0
INSERT INTO Entities (LOGIN, EMAIL)
VALUES #LOGIN, #EMAIL
Unfortunately, it is not possible to include a WHERE condition into UPDATE statements in entity framework so you will have to select, then update or insert, e.g.:
using (var db = new EntityContext())
{
var ent = db.Entities.Where(x => x.ID == 1 && x.LOGIN == null).FirstOrDefault();
if (ent != null)
{
ent.LOGIN = "Whatever";
ent.EMAIL = "Whatever";
}
else
{
db.Entities.Add(ent);
}
db.SaveChanges();
}
Related
I have to update one field in the row of the table after fetching two records from the same row. As an easiest practice I have fetched two records individually, created a new value and then updating that particular property through Entity framework. I think there is a better way to do the same thing with less code. If any body can suggest please.
if (objModel.amountpaid==0)
{
using (estatebranchEntities db=new estatebranchEntities())
{
int rentVar = Convert.ToInt32(db.PropertyDetails.Where(m => m.propertyid == objVM.propertyid).Select(m => m.rent).SingleOrDefault());
int balanceVar = Convert.ToInt32(db.PropertyDetails.Where(m => m.propertyid == objVM.propertyid).Select(m => m.balance).SingleOrDefault());
int balanceUpdateVar = (rentVar + balanceVar);
var propInfo = new PropertyDetail() { balance = balanceUpdateVar };
//var result = (from a in db.PropertyDetails
// where a.propertyid == objVM.propertyid
// select new PropertyDetail
// {
// rent = a.rent,
// balance = a.balance
// }).ToList();
db.PropertyDetails.Attach(propInfo);
db.Entry(propInfo).Property(z => z.balance).IsModified = true;
db.SaveChanges();
}
}
Here is what I think you can do.
Fetch the data once and update once.
using (estatebranchEntities db=new estatebranchEntities())
{
var propDetails = db.PropertyDetails.FirstOrDefault(m => m.propertyid == objVM.propertyid);
if (propDetails != null)
{
int rentVar = Convert.ToInt32(propDetails.rent);
int balanceVar = Convert.ToInt32(propDetails.balance);
int balanceUpdateVar = rentVar + balanceVar;
//now do the update
propDetails.balance = balanceUpdateVar;
db.Entry(proDetails).State = EntityState.Modified;
db.SaveChanges();
}
}
if you need to use the rentVar,balanceVar or the balanceUpdateVar, outside of the using statement then declare them outside it.
I have made a textbox for user to enter id and I want to see if it exists in my table or not
HotelDatabaseDataContext db = new HotelDatabaseDataContext();//database
customer_id = int.Parse(textBox1.Text);//value from textbox
var selected = from x in db.Customers
where x.Id == customer_id//selecting value from database
select x;
/* I want to see if "selected" is null or not and want to store it's value in another variable */
if(selected.id==null)
{
int _id = selected.id;
}
The result of a linq query is an IEnumerable/IQueryable. If you want to check that you have that record use FirstOrDefault:
var item = selected.FirstOrDefault();
if(item != null)
{
int id = item.id;
}
//or:
int id = selected.FirstOrDefault()?.id;
I have this query, it selects A LOT of user records from a table. This code block takes 16 seconds from my local/debug machine (more like 5 in production). Anything I do to make this more efficient doubles the amount of time the method takes to return the results. Examples of other things I've tried are below. I don't understand how selecting an anonymous type and having the extra middle section iterating through the anonymous type can possibly be faster than without.
This block takes 16 seconds:
List<BoAssetSecurityUser> userList = new List<BoAssetSecurityUser>();
using (var context = DataObjectFactory.CreateContext())
{
var query = from ui in context.User_Information
where (ui.AssetCustomerID == 1 &&
(ui.GlobalID != "1TPTEMPUSER" ||
ui.GlobalID == null))
select new { ui };
var result =
from q in query
select new
{
UserId = q.ui.UserID,
FirstName = q.ui.FirstName,
LastName = q.ui.LastName,
UserName = q.ui.Username,
Globalid = q.ui.GlobalID
};
foreach (var user in result)
{
BoAssetSecurityUser boAssetSecUser = new BoAssetSecurityUser();
boAssetSecUser.UserId = user.UserId;
boAssetSecUser.FirstName = user.FirstName;
boAssetSecUser.LastName = user.LastName;
boAssetSecUser.UserName = user.UserName;
boAssetSecUser.GlobalId = user.Globalid;
userList.Add(boAssetSecUser);
}
}
return userList;
This takes over 45 seconds to complete:
List<BoAssetSecurityUser> userList = new List<BoAssetSecurityUser>();
using (var context = DataObjectFactory.CreateContext())
{
var query = (from ui in context.User_Information
where (ui.AssetCustomerID == 1 &&
(ui.GlobalID != "1TPTEMPUSER" ||
ui.GlobalID == null))
select ui).ToList();
foreach (var user in query)
{
BoAssetSecurityUser boAssetSecUser = new BoAssetSecurityUser();
boAssetSecUser.UserId = user.UserID;
boAssetSecUser.FirstName = user.FirstName;
boAssetSecUser.LastName = user.LastName;
boAssetSecUser.UserName = user.Username;
boAssetSecUser.GlobalId = user.GlobalID;
userList.Add(boAssetSecUser);
}
}
return userList;
This example also takes over 45 seconds to complete:
List<BoAssetSecurityUser> userList = new List<BoAssetSecurityUser>();
using (var context = DataObjectFactory.CreateContext())
{
var query = from ui in context.User_Information
where (ui.AssetCustomerID == 1 &&
(ui.GlobalID != "1TPTEMPUSER" ||
ui.GlobalID == null))
select new { ui };
foreach (var user in query)
{
BoAssetSecurityUser boAssetSecUser = new BoAssetSecurityUser();
boAssetSecUser.UserId = user.ui.UserID;
boAssetSecUser.FirstName = user.ui.FirstName;
boAssetSecUser.LastName = user.ui.LastName;
boAssetSecUser.UserName = user.ui.Username;
boAssetSecUser.GlobalId = user.ui.GlobalID;
userList.Add(boAssetSecUser);
}
}
return userList;
This is most likely because ui's type has more properties than the 5 you're interested in. The new { ui } anonymous type is unnecessary; your first example is faster because you tell it before you iterate the list (and thus go to the DB) that you're only interested in those 5 fields. In the other examples, you iterate the list, thus pulling the whole ui objects, even though you only use 5 of its properties.
This code should only pull the 5 properties, and so be as fast as your first example, while being more concise:
List<BoAssetSecurityUser> userList = new List<BoAssetSecurityUser>();
using (var context = DataObjectFactory.CreateContext())
{
var query = from ui in context.User_Information
where (ui.AssetCustomerID == 1 && (ui.GlobalID != "1TPTEMPUSER" || ui.GlobalID == null))
select new
{
ui.UserID,
ui.FirstName,
ui.LastName,
ui.Username,
ui.GlobalID
};
foreach (var user in query)
{
BoAssetSecurityUser boAssetSecUser = new BoAssetSecurityUser();
boAssetSecUser.UserId = user.UserID;
boAssetSecUser.FirstName = user.FirstName;
boAssetSecUser.LastName = user.LastName;
boAssetSecUser.UserName = user.Username;
boAssetSecUser.GlobalId = user.GlobalID;
userList.Add(boAssetSecUser);
}
}
return userList;
It's more about the amount of data your bringing from the database. The first query selects only a few columns while the others bring all of them.
Do you have large columns on this table?
It is faster because you only fetch 5 properties per line with your anonymous type. I don't now how many fields you have in User_Information, but they're all fetched when you use .ToList() on your query, you probably get much more data than needed.
In my web forms, I have text boxes and one radiolist which I need to populate through a LINQ2SQL query. So far I coded this query to fetch particular records which is going to be populated into the DB.
using (dbTestDataContext db = new dbTestDataContext())
{
var query = from r in db.Table1
where r.Code == getCode
select new
{
//Account Info
r.Name,
r.Num,
r.AcctNum,
r.CorpAcct, //Bool
};
};
Now I know that the record which this query is going to be fetching is gonna be only 1 unique record. I want to show the record in these textboxes and select that radio button:
tbName
tbNum
tbAcctNum
rbtnCorpAcct
How should I do this? Thank you in advance!
Very simply:
using (dbTestDataContext db = new dbTestDataContext())
{
var query = (from r in db.Table1
where r.Code == getCode
select new
{
//Account Info
r.Name,
r.Num,
r.AcctNum,
r.CorpAcct, //Bool
}).FirstOrDefault();
if (query != null)
{
tbName.Text = query.Name;
tbNum.Text = query.Num;
//and so on
rbl.SelectedValue = query.SomeValue;
}
};
Same as others have answered with addition of radio button:
tbName.Text = query.Name;
tbNum.Text = query.Num;
tbAcctNum.Text = query.AcctNum;
if(query.CorpAcct)
rbtn.SelectedValue = "Yes"; \\Where "Yes" is one of the radio button values
else
rbtn.SelectedValue = "No";
\\Could also use SelectedIndex, rbtn.SelectedIndex = 0 or 1
Try the following:
using (dbTestDataContext db = new dbTestDataContext())
{
var query =
(
from r in db.Table1
where r.Code == getCode
select new
{
//Account Info
r.Name,
r.Num,
r.AcctNum,
r.CorpAcct, //Bool
}
).FirstOrDefault();
tbName.Text = query.Name;
....
};
The first thing you need to do is retrieve a single result from your query. As you have it written, you are returning an IQueryable object which is now stored in the variable "query"
To get a single object, do this
var myObject = query.SingleOrDefault();
Then you can access the individual properties of that object and assign them like this
tbName.Text = myObject.Name
I have 2 tables Users and Queries. They are connected via FK(UserId) in Queries table.
I need to add queries added, for example, by user with login "Bob" to all users.
Here is a chunk of code i'm using:
public bool SaveUserQuery(string userName, Query query) {
var db = new UserDataClassesDataContext();
Table<User> users = db.Users;
if ( userName.ToLower() == "bob" ) {
foreach ( var user in users ) {
var tempQuery = new Query();
tempQuery.Name = query.Name;
tempQuery.FolderName = query.FolderName;
tempQuery.Layout = query.Layout;
tempQuery.Description = query.Description;
tempQuery.Query1 = query.Query1;
tempQuery.UserID = user.UserId;
try {
user.Queries.Add(q);
}
catch (Exception e) {
Logger.Log.Error("attach", e);
}
}
db.SubmitChanges();
return true;
}
}
It throws error when adding:
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Queries_Users". The conflict occurred in database "OLAPUsers", table "dbo.Users", column 'UserId'.
How can i fix this or archive the goal i have?
Make sure that your primary keys are setup correctly in the DB schema. You can query tables without primary keys, but you can't do inserts unless everything is setup correctly, and the data context's view of the DB is current.
Try this:
public bool SaveUserQuery(string userName, Query query)
{
var db = new DataContext();
if ( userName.ToLower() == "bob" )
{
List<Query> queries = new List<Query>();
foreach ( var user in db.GetTable<Users>())
{
Query tempQuery = new Query(query.Name, query.FolderName, query.Layout, query.Description, query.Query1, user.UserId);
//and ofc create this constructor
queries.Add(tempQuery);
}
db.GetTable<Query>().InsertAllOnSubmit(queries);
db.SubmitChanges();
return true;
}
}