I have a table with nvarchar field (MS SQL Server 2008 R2). For testing, this code works fine:
Update [Screenshots] set name=N'Значение' where id=230246
right now I created Entity Framework model, I have set Unicode as True
then I try to update my record:
public void Put(FormDataCollection formData)
{
string filename = formData.Get("filename");
var screenshot = c.Screenshots.Where(p => p.filename == filename).FirstOrDefault();
if (screenshot != null)
{
screenshot.name = formData.Get("description");
c.SaveChanges();
}
}
but I got "?????" instead of unicode value. How to do it? I know about AsNonUnicode method, but this method works only for LINQ.
Are you sure that formData.Get("description") returns UTF-8 string (that it isn't converted somewhere)?
What is your approach in entity framework? Code-first/Design-first/Database-first?
Try to remove database and recreate - remove database and then in designer right click -> Generate database from model...
Get Entity Framework Profiler from Nu-get package manager and see what query is sending to database.
Related
Can u tell me what is the problem?
If you are using two different instances of the DbContext (the db variable as you named it) then nothing will be saved when you call SaveChanges on a context different than the one where your entities are tracked. You need to use the Attach method first.
db.customer_images.Attach(item);
db.SaveChanges();
However I think in your case you can avoid the attach step if you refactor a bit you code and don't use the DbContext from the entity itself.
Before going through my answer, you must check, if you are attaching the item as shown in excepted answer or check this code:.
if (dbStudentDetails != null && dbStudentDetails.Id != 0)
{
// update scenario
item.Id = dbStudentDetails.Id;
_context.Entry(dbStudentDetails).CurrentValues.SetValues(item);
_context.Entry(dbStudentDetails).State = EntityState.Modified;
}
else
{
// create scenario
_context.StudentDetails.Add(item);
}
await _context.SaveChangesAsync();
If above solution doesn't work, then check the below answer.
Saw a very wired issue, and thought to must answer this. as this can
be a major issue if you have lots of constraints and indexes in your
SQL.
db.SaveChanges() wasn't throwing any error, but not working (I have tried Exception or SqlException). This was not working because the Unique constraint was not defined properly while creating the Entity Models.
How you can Identified the issue:
I connected my SQL Server and opened the SQL Profiler.
Just before the db.SaveChanges(), I cleared all my profiler logs and ran the db.SaveChanges(). It logged the statement. I copied the script from the profiler and ran the script in SQL Server.
And bingo, I can see the actual error, which is being thrown at SQL Server side.
(images: have some hints, how you can get the execute statement from Profiler and run on sql server)
What you can do For Entity Framework Core:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Students>().HasIndex(p => new { p.RollNumber, p.PhoneNumber }).IsUnique(true).IsClustered(false).HasDatabaseName("IX_Students_Numbers");
}
What you can do For Entity Framework 6 and below:
using System.Data.Entity.ModelConfiguration;
internal partial class StudentsConfiguration : EntityTypeConfiguration<Students>
{
public StudentsConfiguration()
{
HasIndex(p => new { p.RollNumber, p.PhoneNumber }).IsUnique(true).IsClustered(false).HasName("IX_Students_Numbers");
}
}
Try to query your entity by Id, eg:
entity = this.repo.GetById(item.id);
entity.is_front = false;
if (dbSaveChanges() > 0)
{
....
}
I am using the Entity Framework in a MVC Web API and I can't figure out why the changes aren't being saved to the database. I am using the following code:
[HttpPost]
public HttpResponseMessage PostPXE(PXE pxe)
{
var pxeRequestID =
from qsp in db.Queue_Server_Provision
.Where(a => a.Server_Name == pxe.Server_Name)
join isni in db.IaaS_Server_NIC_Information
.Where(a => a.MAC == pxe.Mac_Address)
on qsp.IaaS_ID equals isni.IaaS_Server_Information_IaaS_ID
select qsp.Request_ID;
var QSP = db.Queue_Server_Provision.Find(pxeRequestID.FirstOrDefault());
db.Queue_Server_Provision.Attach(QSP);
QSP.Provision_Status_Code = "240.9";
db.Entry(QSP).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException e)
{
return Request.CreateResponse(HttpStatusCode.NotFound, e.Message);
}
catch (Exception e)
{
return Request.CreateResponse(HttpStatusCode.NotFound, "error");
}
return Request.CreateResponse(HttpStatusCode.OK);
}
While debugging everything seems to work fine until I call the SaveChanges() method, at that point the Provision_Status_Code value reverts to what it was before being modified.
The following SQL is generated from the Entity Framework:
exec sp_executesql
N'update [dbo].[Queue_Server_Provision]
set [Server_Name] = #0,
[Environment_List_ID] = #1,
[Operating_System_List_ID] = #2,
[Container_Size_List_ID] = #3,
[Active_Directory_List_ID] = #4
where ([Request_ID] = #5)
select [IaaS_ID],
[Provision_Status_Code],
[Provision_Status_Text],
[Provision_Phase],
[Last_Update_Time],
[Canceled]
from [dbo].[Queue_Server_Provision]
where ##ROWCOUNT > 0 and [Request_ID] = 5',
N'#0 nvarchar(16),
#1 uniqueidentifier,
#2 uniqueidentifier,
#3 uniqueidentifier,
#4 uniqueidentifier,
#5 uniqueidentifier',
#0=N'IaaSTest222',
#1='31097372-E4A6-461D-AFCC-BFAF069A6710',
#2='CF44FE08-56DE-4A7D-813A-08A7AD215E8B',
#3='15AEB74F-E0CB-4219-AC69-8C623DE8DF46',
#4='EA08BB7E-5C1F-4F6B-83D6-4BF9F6C55FF7',
#5='34CA5F9C-2BF8-40E5-8BDD-5DE7364C18C3'
This looks very much like Entity Framework "thinks" that the Provision_Status_Text column is generated in the database - either because it's an identity (unlikely for a string column) or because it's a computed column.
Indication for this is:
The column is not part of the set expression in the update statement although you changed that column. If the column is database generated this is expected.
The column is returned in the sql select expression. For a database generated column this is expected again because EF wants to update the entity on client side with the current computed database values after an insert or update.
The same applies by the way for the other columns that occur in the select statement.
If you are using Code-First workflow check if those properties are annotated with one of the
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
attributes or if
....HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
....HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed)
is used with Fluent API.
If you are using Database-First or Model-First workflow with EDMX check your EDMX file for StoreGeneratedPattern="Identity" or StoreGeneratedPattern="Computed" attributes. You should find these settings in the designer surface as well.
It does not necessarily mean that the column is really generated in the database. But if one of these settings is in the model metadata EF will assume it is and behave the way you see it. It could mean that database and model are "out of sync" for some reason because some manual changes have been done in the database schema or the model perhaps without updating the other side.
I"m using VS 2010 & EF 3.5. I've imported a stored procedure which returns a list of guids using the Function Import feature. How do I invoke it in my code? After instantiating the dbcontext, intellisense doesn't display the procedure I've imported. I know it's pretty easy in EF 4.0 but I'm stuck with EF 3.5 for this project. Any ideas on how get around this other than doing it the old-fashioned way?
I don't think EF versions prior to 4 can use imported stored procedures that don't return entities. That is, your stored procedure must return a complete entity object in order for EF to use it. Since your procedure only returns a list of GUIDs, EF doesn't know how to use it.
You can put this in your partial data-context class to call the procedure:
public IEnumerable<Guid> GetMyGUIDs()
{
if (this.Connection.State != System.Data.ConnectionState.Open)
this.Connection.Open();
var command = new System.Data.EntityClient.EntityCommand
{
CommandType = System.Data.CommandType.StoredProcedure,
CommandText = #"YourContext.YourProcedureName",
Connection = (System.Data.EntityClient.EntityConnection)this.Connection
};
var list = new List<Guid>();
using (var reader = command.ExecuteReader())
{
// get GUID values from the reader here,
// and put them in the list
reader.Close();
}
return list;
}
I'm currently planning on switching my "manual query-writing" code to a nice SQL framework, so I can leave the queries or sql things to the framework, instead of writing the queries myself.
Now I'm wondering how I can get a single record from my table in Entity Framework 4?
I've primarily used SQL like SELECT * FROM {0} WHERE Id = {1}. That doesn't work in EF4, as far as I'm concerned.
Is there a way I can select a single ID-Based record from my Context?
Something like:
public Address GetAddress(int addressId)
{
var result = from Context.Addresses where Address.Id = addressId;
Address adr = result as Address;
return Address;
}
Thank you!
var address = Context.Addresses.First(a => a.Id == addressId);
You can use Single or First methods.
The difference between those methods is that Single expects a single row and throws an exception if it doesn't have a single row.
The usage is the same for both of them
(Based on VS 2015) If you create an .edmx (Add --> ADO.NET Entity Data Model).
Go through the steps to created the ".edmx" and use the following to run the stored procedure. emailAddress is the parameter you are passing to the stored procedure g_getLoginStatus. This will pull the first row into LoginStatus and status is a column in the database:
bool verasity = false;
DBNameEntities db = new DBNameEntities(); // Use name of your DBEntities
var LoginStatus = db.g_getLoginStatus(emailAddress).FirstOrDefault();
if ((LoginStatus != null) && (LoginStatus.status == 1))
{
verasity = true;
}
I use Entity Framework 4.0 and need to prefilter all queries using TennantId. I modified T4 template to add pre-filter to all ObjectSets like so and it works for "regular" part of the application.
public ObjectSet<Category> Categories
{
get
{
if ((_Categories == null))
{
_Categories = base.CreateObjectSet<Category>("Categories");
_Categories = _Categories.Where("it.TenantId = 10");
}
return _Categories;
}
}
The problem I have is that ASP.NET Dynamic Data doesn't invoke these methods and goes directly to CreateQuery which I cannot override.
Is there any way to prefilter data in this scenario?
You can set a condition for each entity in your Edm and EF will automatically append that condition in the "Where" clause of all the queries it generates.
See my answer to here that might help you.