mvc Entity Framwork, insert using select max() from table - entity-framework

I am developing an App using MV5 and Entity Frameowrk to connect to SQL Server Database
I need to do an Insert where the is getting ID like this.
Select max(id)+1 from table where field_id = #ID.
The idea is to do it in one transaction.
Is that Posible to do it in Entity Framework or I should use a Store Procedure?

EF compiles the C# expressions you provide it into SQL, and then executes the resulting SQL. So you can write such a query in LINQ, which will in-fact be computed during a single "call" to the database:
long id = MyDbContext.MyDbSet.Max(entity => entity.Id) + 1;
Do note, that if you are doing this so that you can assign a non existing ID to a new entry- there's no need. EF takes care of this for you, so long as the field is named Id and it is of type long. Just do not assign it any value.

Related

EF5 - modify generated insert/update statement before SaveChanges()

I need to modify the generated SQL for insert/update operation, before it is sent to database. The required modification is very specific, so I was hoping that there is a way to simply append string to statement.
For example, SQL looks like this (Oracle BTW):
UPDATE TABLE_A
SET DESCRIPTION = "ABC"
WHERE OBJECTID = 1
But I want to append this line (in SET part) to update one more field:
SHAPE = sde.st_geometry('point (18 57)', 4326)
I can't add SHAPE column to EF model, because that is unsupported data type.
Now, is there a way I can modify EF generated SQL statement?
You could move this update to a simple stored procedure that is mapped into your entity data model.

EF 6 Migration: How to execute sql SELECT?

In our project we have necessity of adding some predefined data to DB. I think the best way and concept is using for that EF Migrations (not Seed method).
But we have a big troubles with adding related data to DB:
For Example:
Suppose we have 2 tables:
Users:
Id (PK auto increment)
Name
RoleId
Roles:
Id (PK auto increment)
Name
Let's suppose that we need to add User(Name = 'John', RoleId = (Id of role that name is 'Admin')).
How can we do it? It would be great if we find a solution that allows us to execute pure SQL SELECT script which not uses Entities of Code First because they can be modified or removed.
For DELETE, INSERT, UPDATE can be used Sql(...) method but what about SELECT?
You cannot have a context into the migration.
Logically first are ran the migrations to Update the DB Schema, then you can have a context to work with the data via it. If your DB does not match the model, or even the table is still not there, you cannot use it in EF.
I had to look into the EF code (and also because was curious). Practically the Sql() method in the DbMigration class in several levels below just adds the SQL string into a list of queries that should be executed into the transaction and moves on. It does not executes it when it is called. So in short EF just fills in a list of codes lines that should be executed in the end at once. And it seems correct if you try to walk in all paths of what you can do with the C# code in the migration code.
The question is quite good actually, unfortunately still I didn't found any better solution rather than using pure ADO.
Another option is to generate more custom SQL queries, and use T-SQL more widely.
For your case as you want to insert the user and set the groupId looking by the name, it can be used with inner select:
INSERT INTO Users (Name, GroupId)
VALUES ('John', RoleId = (SELECT Id FROM Roles WHERE Name = 'Admin')).
For my issue, I had to a bit do more sophisticated execution - the following does the same as the AddOrUpdate method of the DbSet, using the IF statement:
IF EXISTS (SELECT * FROM Table1 WHERE Column1='SomeValue')
UPDATE Table1 SET (...) WHERE Column1='SomeValue'
ELSE
INSERT INTO Table1 VALUES (...)
I found it here: http://blogs.msdn.com/b/miah/archive/2008/02/17/sql-if-exists-update-else-insert.aspx
I'm using good old LINQ for this:
public override void Up()
{
using (var dc = new DbContext("your connection string or name"))
{
var ids = dc.Database.SqlQuery<int>("SELECT id FROM sometable WHERE somefield={0}", 42).ToArray();
...
}
}
Using LINQ is better, even for usual migrations, because, there is a bug in DbMigration.Sql method, it ignores arguments: How to pass parameters to DbMigration.Sql() Method

Entity Framework Generate Database Schema (SQL) with Default Table Values

I am using EF 5 and SQL Server 2005, Model First (sort of).
By sort of, I mean that I typically build my schema in the SQL Server designer, but import the schema into EF so I have a visual view. There is often round-tripping.
However, I noticed that when I try to generate the DB schema based on the EF model, it skips all of the NEWID() default values that I have assigned as default values to my Guid IDs, but it doesn't skip the identity fields of type int.
I found this post explaining the reasoning for this:
Entity Framework 4 and Default Values
However, it doesn't answer my question: How do I get Entity Framework to generate a SQL DDL database schema with default values of NEWID() for my uniqueidentifier types?
NOTE:
I don't care about how to set them from the POCO entities and so forth (there are plenty of posts describing that) - my concern is getting the SQL DDL generated right so I can seed the database without worrying about these values going missing.
Using Entity Framework Migrations, you can use the GUID column builder and its DefaultValueSql parameter. The value of that parameter can be the string "NEWID()". This should take care of proper DDL generation.
Next you should declare these properties as database-generated using attributes or the fluent model builder, so that EF ignores the values set in your POCOs (which will be null for new objects).

Create entity and return ID

Using Open JPA 2.0, and database is DB2 9.7. I would like to like to create an entity which includes ID which is Primary Key, and auto generated Identity column and after creating the entity I need to display the ID generated. For this after persisting the entity, I am calling entity.getId().
In the database, I see below query getting executed
select ID from final table
(INSERT INTO WEB.USER (NAME, LOCATION) VALUES (?, ?))
Is there any alternate / better way to create an entity and return the generated ID? I would like to avoid "Select ID from final table", as this is expected to have performance impact.
This is how you retrieve auto generated ID from DB2 and there is nothing you can do about it. Other databases often require extra SQL query, so it's actually even better with DB2, which returns ID immedaitely. I don't think there is a faster way to so this.
Check out OPENJPA-736 where this optimization was implemented.
I am using Database sequence (#SequenceGenerator) to avoid "select ID from final table". This worked fine and #TableGenerator would also have sorted this issue.

Join to Stored Procedure Using Entity Framework

I have a stored procedure that grabs data recursively. I did a function import in my entity set. I can create a function in my ObjectContext that looks like this:
public ObjectResult<ProviderAccountSetting> GetProviderAccountSettings(long providerAccountId)
{
string functionName = "MyContainer.GetProviderAccountSettings";
ObjectParameter providerAccountIdParameter = new ObjectParameter("providerAccountId", providerAccountId);
ObjectResult<ProviderAccountSetting> results = context.ExecuteFunction<ProviderAccountSetting>(functionName, providerAccountIdParameter);
return results;
}
However, I cannot perform a join with LINQ without getting an error. Is there a way to tell Entity Framework to use the stored procedure whenever I access an entity? I would like my stored procedure to be used any time I grab data for that entity. Furthermore, I want it to work with joins. Does Entity Framework support this type of stored-procedure to table mapping? Otherwise, is there a way to join a function import?
Neither of your requirement is possible. You cannot tell EF to use stored procedure every time when you query data. You must manually call your GetProviderAccountSettings to call stored procedure. You also cannot use join (on database side) when using stored procedures (it is even not possible in SQL directly). If you need to join any data to result set of your stored procedure it must be done directly in the procedure and returned as result set. Otherwise you must execute your stored procedure and joined query separately and join them in linq-to-objects.