I'm try insert this row to my table
student (
id (int)
,name (nvarchar)
)
But when I insert this value (1,"bơ") to student result in my database is
(1,"bo?")
this is my code
public bool Insert() {
Admin_KX_MainDbEntities db = new Admin_KX_MainDbEntities();
student student = new student() {
id = 1,
name = "bơ"
};
db.students.add(student);
db.SaveChanges();
}
Related
I have a table with:
id
employee_name
manager_id
In this table, manager id is a foreign key to id in same table.
I have another table with projects
id
employee_id
In this table, employee_id is a foreign key to id in the employee table
I try to get the name from the manager_id like this in the controller:
public function show(Employee $managers, $id)
{
$manager = $managers::find($id)->manager;
\Debugbar::info($manager);
}
And my App\Employee file is like this:
class Employee extends Model {
protected $table = 'employees';
public $timestamps = true;
public function projects()
{
return $this->hasMany('App\Projects');
}
public function manager()
{
return $this->hasOne('App\Employee');
}
}
The proble is I get:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'employees.employee_id' in 'where clause' (SQL: select * from `employees` where `employees`.`employee_id` = 1 and `employees`.`employee_id` is not null limit 1)
To me it shows that it is taking employee_id in the sal statement from the other function where it should only take id as it is in the same table.
You should change:
public function manager()
{
return $this->hasOne('App\Employee');
}
into
public function manager()
{
return $this->belongsTo('App\Employee','manager_id');
}
You can do it without the manager_id I expect the 2nd parameter is for when you have an id that does not follow the tablename_id convention.
public function manager()
{
return $this->belongsTo('App\Employee');
}
I have create a table with this schema :
CREATE TABLE [dbo].[A](
[KeyID] [uniqueidentifier] NOT NULL,
[OtherID] [uniqueidentifier] NULL,
[Info] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_TX_A] PRIMARY KEY CLUSTERED
(
[KeyID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
I have created this POCO Class :
public partial class A
{
public A()
{
}
public System.Guid KeyID { get; set; }
public Nullable<System.Guid> OtherID{ get; set; }
public string Info{ get; set; }
}
When I try to insert a new line in my table with Entity Framework :
[TestMethod]
public void TestAdd( )
{
A a = new A( );
Guid myKey = Guid.Parse("9B3CA1AC-279F-48CE-B693-D5329FF3AD14");
a.OtherID = myKey;
a.KeyID = myKey;
a.Info = "Test";
using( var database = new myConnection( ) )
{
database.A.Add( a );
database.SaveChangesAsync( ).Wait( );
}
}
It produces this SQL command :
DECLARE #generated_keys table([A] uniqueidentifier)
INSERT [dbo].[A]([OtherID], [Info])
OUTPUT inserted.[KeyID] INTO #generated_keys
VALUES (#0, #1)
SELECT t.[KeyID]
FROM #generated_keys AS g JOIN [dbo].[A] AS t ON g.[KeyID] = t.[KeyID]
WHERE ##ROWCOUNT > 0
Then it generates this error :
Can not insert the value NULL into column 'KeyID', table 'A. This column does not accept NULL values. INSERT failed.
It seems it doesn't take into account the primary key ID specified and it seems to believe that the primary key is auto incremented.
But this SQL statement works fine in SQL Server :
INSERT INTO A (KeyID, OtheriD, Info)
VALUES('9B3CA1AC-279F-48CE-B693-D5329FF3AD14', '9B3CA1AC-279F-48CE-B693-D5329FF3AD14', 'test')
Do you know what's wrong ?
Thanks for your help.
Your Entity Framework configuration is set up for database-generated primary key columns, that's why you also see in the SQL how EF attempts to retrieve the new KeyID value even though it hasn't set it. Your primary key column isn't database-generated, so this can never work.
If you let EF generate your database for you, you would have got a matching one. If you create your database manually, it has to match what EF thinks it should be, or you get errors like this.
You can chance your model to not treat the key column as database-generated with the DatabaseGenerated attribute, specifying DatabaseGeneratedOption.None.
use this code :
public void TestAdd( )
{
A a = new A( );
Guid myKey = Guid.NewGuid();//use this
a.OtherID = myKey;
a.KeyID = myKey;
a.Info = "Test";
using( var database = new myConnection( ) )
{
database.A.Add( a );
database.SaveChangesAsync( ).Wait( );
}
}
I am trying to use EF with an insert stored procedure as I have no direct access to the table. My understanding is the database should not get updated until SaveChanges() is called in the code but database is updated everything an insert happens. In this case, 4 database calls were made.
How do I make this to have just one database call and update multiple records?
This may be classed as database-first EF? The stored procedure is imported as a function to edmx in a normal way.
Code sample:
public ActionResult Index()
{
List<Product> products = new List<Product> {
new Product() { Title = "coca cola", Description = "good"},
new Product() { Title = "apple", Description = "fruit"},
new Product() { Title = "orange", Description = "fruit"},
new Product() { Title = "banana", Description = "my favourite"}
};
EFwithSPtest context = new EFwithSPtest();
foreach(var p in products)
{
context.Insert(p.Title, p.Description);
}
context.SaveChanges();
return View();
}
Stored procedure:
ALTER PROCEDURE [dbo].[Insert]
#Title nvarchar (50),
#Description nvarchar (max)
AS
INSERT INTO [Product] (Title, Description) VALUES (#Title, #Description)
RETURN 0
Auto generated DbContext class:
public partial class EFwithSPtest : DbContext
{
public EFwithSPtest()
: base("name=Entities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual int Insert(string title, string description)
{
var titleParameter = title != null ?
new ObjectParameter("Title", title) :
new ObjectParameter("Title", typeof(string));
var descriptionParameter = description != null ?
new ObjectParameter("Description", description) :
new ObjectParameter("Description", typeof(string));
return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction("Insert", titleParameter, descriptionParameter);
}
}
I have an InsertPerson stored procedure and i need it to return a GUID (Uniqueidentifier) into my person object that is being created. Is this even possible with entity framework codefirst? I've tried everything and entity framework is ignoring the guid im trying to return using an output parameter. Does anyone have an example if this is possible?
Person.cs:
public class Person
{
public Guid Id { get; set; }
public string FirstName { get; set; }
}
Stored Procedure:
CREATE PROCEDURE [dbo].[InsertPerson]
#KeyPlayerId UNIQUEIDENTIFIER ,
#FirstNameNVARCHAR(255)
AS
-- Perform Insert
insert into [dbo.].[Person]....
-- Return GUID
select #Id as [Id];
END;
I was able to accomplish it by telling Entity Framework that the Id is a Database Generated value. I mapped the Insert procedure to InsertPerson in the PersonMap class and use that when the model is created in the OnModelCreating method. In the stored procedure I generate a new Id and pass this back to Entity Framework. Hope this helps!
PersonMap.cs
public class PersonMap : EntityTypeConfiguration<Person>
{
public PersonMap()
{
// Primary Key
this.HasKey(t => t.Id);
// Tell Entity Framework the database will generate the key.
this.Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
// Properties
this.Property(t => t.FirstName)
.IsRequired()
.HasMaxLength(255);
//Map to Stored Procedure
this.MapToStoredProcedures(s => s.Insert(i => i.HasName("InsertPerson")));
}
}
OnModelCreating
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new PersonMap());
}
InsertPerson Stored Procedure
CREATE PROCEDURE InsertPerson
-- Since Id is marked as Database Generated we only need
-- a parameter for First Name
#FirstName nvarchar(255) = 0
AS
-- Variable to hold new Id
DECLARE #Id uniqueidentifier
-- Generate a new Id using NEWID function that returns a unique identifier
SET #Id = NEWID()
-- Perform Insert
INSERT INTO [dbo].[Person] VALUES (#Id, #FirstName)
-- Return the Id to Entity Framework
SELECT #Id AS 'Id'
I think this may help you:
var sqlConnection1 = new SqlConnection("Your Connection String");
var cmd = new SqlCommand();
var reader;
cmd.CommandText = "StoredProcedureName";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Connection = sqlConnection1;
sqlConnection1.Open();
reader = cmd.ExecuteReader();
rdr = cmd.ExecuteReader();
var outputValue = Guid.Parse(cmd.Parameters["#Response"].Value.ToString());
sqlConnection1.Close();
I have two tables as follows:
Departments:
DeptID (PK)
DeptName
...
Employees:
EmpID (PK)
DeptID (FK)
EmpName
...
and I have a query using LINQ as follows:
public List<Employee> GetEmployee(int deptID)
{
var query = from e in mdc.Employees
join d in mdc.Departments on e.DeptID equals d.DeptID
where e.DeptID == deptID
select new { e.EmpID, e.EmpName, d.DeptName };
return query.ToList();
}
Now my question is this. I would like to select the fields EmpID, EmpName, and DeptName.
But what will my return type be? This one returns an error because this query returns a GenericList as opposed to my List<Employee>.
You need to create another class with required properties like this,
public class NewType{
public EmpID{get;set;}
//other fields here
}
and then select ,
public List<NewType> GetEmployee(int deptID)
{
var query = from e in mdc.Employees
join d in mdc.Departments on e.DeptID equals d.DeptID
where e.DeptID == deptID
select new NewType{ e.EmpID, e.EmpName, d.DeptName };
return query.ToList();
}