Add, Update and delete using single transaction EF 6? - sql

I have method which has following signature
performAmmend(Project project, List witem, List cConfig)
the relationship is
Project->WorkItem ( 1 to many)
WorkItem->CustomConfig( 1 to many )
List parameter could have some new entries, modified or deleted
How to perform update operation for the project using transaction?
i am using code first approch in Entity framework 6.x.

EF will give you a transaction by default. So simply setup your object graph and apply SaveChanges(). OK, deep object graphs aren't simple, but you could use a tool like graphdiff

Related

Validating against a duplicate entry in ASP.NET 5 MVC 6

Using asp.net 5, MVC 6, code first, entity Framework 7, beta 8.
I understand that some validation can be handled through annotations on properties, e.g. Data Type, min, max values and the jquery scripts, but I'm not sure how in code validation against a duplicate entry getting into the database, like preventing a duplicate e-mail reg on a form.
Is there any annotation that I can use for this on my model property or do I need to code something in my controller to handle this custom validation? Anyone got an example to share?
EF7 does not have any magic to prevent duplicate values in a table. The only way to validate duplicates is to make a roundtrip to the database. The best way to do this is with a unique constraint. This may be expressed as a unique index. Any attempt to insert a duplicate entry should throw an exception.
That said, you can configure EF7 to recognize the unique index in your database in your OnConfiguring method. See Indexes : Configuring Your Model in the EF7 docs.
modelBuilder.Entity<User>()
.Index(b => b.Email)
.Unique();

Include count of linked records in OData result

I've got a table "Events" with a linked table "Registrations", and I want to create an OData service that returns records from the Events table, plus the number of registrations for each event. The data will be consumed client-side in JavaScript, so I want to keep the size of the returned data down and not include all linked registration records completely.
For example:
ID Title Date Regs
1 Breakfast 01.01.01 12:00 4
2 Party 01.01.01 20:00 20
I'm building the service with ASP.NET MVC4. The tables are in an MSSQL database. I am really just getting started with OData and LINQ.
I tried using the WebAPI OData system first (using classes of EntitySetController) but was getting cryptic server errors as soon as I included the Registrations table in the entity set. ("The complex type 'Models.Registration' refers to the entity type 'Models.Event' through the property 'Event'.")
I had more success building a WCF OData system, and can request event information and information on related registrations.
However, I have no clue how to include the aggregate count information in the event result set. Do I need to create a custom entity set that will be the source for the OData service? I probably included too litte information here for finding a solution, but I don't really know where to look. Can somebody help me?
If you're willing to make an extra request per Event, you could query http://.../YourService.svc/Events(<key>)/Registrations/$count (or http://.../YourService.svc/Events(<key>)/$links/Registrations?$inlinecount=allpages if you're also using the links to the Registration entities).
Examples of both of these approaches on a public service:
http://services.odata.org/V3/OData/OData.svc/Suppliers(0)/Products/$count
http://services.odata.org/V3/OData/OData.svc/Suppliers(0)/$links/Products?$inlinecount=allpages&$format=json
I'm guessing that you'd prefer this information to come bundled together with the rest of the Events response though. It's not ideal, but you could issue a query along these lines:
http://services.odata.org/V3/OData/OData.svc/Suppliers?$format=json&$expand=Products&$select=Products/ID,*
I'm expanding Products (analogous to your Registrations) and selecting Products/ID in order to force the response to include an array that is the same size as the nested Products collection. I don't care about ID -- I just chose a piece of data that would be small. With this JSON response, your javascript client can get the length of the Products array and use that as the number of Products that are linked to the given Supplier.
(Note: to have your service support $select queries using WCF Data Services, you'll need to include this line when you initialize the service: config.DataServiceBehavior.AcceptProjectionRequests = true;)
Edit to add: The approach using $expand and $select won't be guaranteed to give you the correct count if your server does server-driving paging. In general, there isn't a simple single-response way to do what you're asking for in OData v3, but in OData v4, this will be possible with the new expand/select syntax.
i'm using oData v4 and i used this syntax :
var url = '.../odata/clients?$expand=Orders($count=true)';
// ...
a field called Orders#odata.count has been added to the response entity which contains the correct count.
and now to access the JSON property containing a dash you have to do it like this :
var ordersCount = response.value['Orders#odata.count'];
hope this helps.
Can you edit your Event model and add a RegistrationCount property? That'd be the simplest way I think
What I ended up doing was actually very simple; I created a View in SQL Server that returns the table including the registration counts. Never thought about using a view, since I've never used them before...
I used this to get the child count without returning the entities:
/Parents$expand=Children($count=true;$top=0)

SubmitChanges with LINQ to SQL and User Defined Functions

On the SQL server I create a UDF. Let's name it fnCompanyDetails. It selects some information about a company from several joint tables.
I then drag-and-drop this function in the new .dbml of my VB project. I want to use it with LINQ. Smth like this:
Dim company = (From c In d.fnCompanyDetails(sap)
Select New With {
.Sap = c.txtSAP,
.CompanyName1 = c.txtCompanyName1, _
.CompanyName2 = c.txtCompanyName2, _
})
The result of this query I display to the user in a form. If some field is changed I want to send the changes to my database, but is this possible if I'm quering like this, from a UDF?
Thank y
No, it is unfortunately not possible to do in a simple way. Linq-to-sql supports reading to custom types, but only support updates through the entity types that exactly corresponds to a table.
Normally the best way is to always read pure entity objects if they are read with the intention to update them.
Another solution is to create entity objects out of the data returned from the udf and then attach those entities to the context. If you attach the entities in their original state first and then make changes after attaching, you should get away without any change tracking problems.

How to rename a column/proprety within fluent NHibernate?

Say I already have a Table:
Customer
First
Last
Thus I would have an object with properties such as:
Customer.First
Customer.Last
If I wanted to refactor the code so that I rename the properties:
Customer.FirstName
Customer.LastName
Is there a way to indicate to NHibernate to update First to FirstName and so on?
I already know how to update using SchemaUpdate, but it just adds those two properties as new columns. Is there a way to indicate to re-map?
Thanks,
Gally
Use a DB migration tool for that. Here's a list of options for doing database migrations in .NET

Table not getting updated while using LinQ

I am trying to update a table using LinQ. Though records are getting inserted, for some reason they are not getting updated.
what can be possible problem
Dim db as new empDataContext
Dim emptable as new employee
if update then
emptable=GetEmp(txtempID.Text)
emptable.Name="Test"
emptable.Age=11
emptable.City="NYC"
else
emptable.Name="Test"
emptable.Age=11
emptable.City="NYC"
emtable.deptID=10
db.employee.InsertOnSubmit(emptable)
end if
db.SubmitChanges()
Judging just from what I can see here, I'm guessing your GetEmp method is using a different data context to retreive the data than the one you're using to save it back to the DB.
When using LINQ to SQL, the context is what tracks the changes to the tables. If you're not careful and mix Contexts by accident, you can get strange behaviors like this.
You can test by chaging:
emptable=GetEmp(txtempID.Text)
to
// Returns the first matching employee with the id
emptable = (from e in db.Employees
where e.id == txtempid.Text).FirstOrDefault()
If you find that the context is the issue, just modify your GetEmp method to accept the context as a parameter rather than creating a new one itself.
What does GetEmp do? In particular, as presented it appears that it does not have a reference to the empDataContext named db. DataContexts are examples of identity maps and as such they track items that have been loaded from a persistence mechanism. If you are using a different DataContext in GetEmp then the DataContext db does not know about the instance of employee with SomeID equal to the value represented by txtempID.Text.
So either pass a reference to db into GetEmp or change your code to the following:
emptable = db.Single(Function(e as employee) e.SomeID=Int32.Parse(txtempID.Text))
then your update should work.
If I had to guess, I would say that the GetEmp() call is not using the same database context object. Therefore, Linq-To-SQL doesn't think any changes are occuring in the "db" database context.
Randy