ObjectContext DeleteObject - entity-framework

Below is my working table.
OrderID ProductID UnitPrice
1 P001 10
1 P002 11
1 P003 12
2 P001 10
I use below code to make delete every row(s) which orderID is 1.
void DeleteOrderMaster(int OrderID)
{
Order _Order = DB.Orders.SingleOrDefault(x => x.OrderID == OrderID);
DB.Orders.DeleteObject(_Order);
}
What my problem is about ...
ObjectContext.Table.DeleteObject(entity);
As I am not very familiar with DeleteObject function, I want to call that function like that
DeleteOrderMaster(1)
Please let me know is this correct way or not ?

ObjectContext.DeleteObject(object entity) method delete any entity that is not in detached state (object context is not set).
void DeleteOrderMaster(int OrderID)
{
Order _Order = DB.Orders.SingleOrDefault(x => x.OrderID == OrderID);
if(_Order!=null)
DB.DeleteObject(_Order);
}

Order _Order = DB.Orders.SingleOrDefault(x => x.OrderID == OrderID);
db.Orders.DeleteObject(_Order);
db.SaveChanges();
Remove is a method of DbSet class which can only be created from a DbContext class which is a part of Entity Framework.
EDIT
May be I confused myself, which as a result confused you. First of all apologies for that.
Now, coming back to explanation, you are indeed using the Entity Framework. The ObjectContext Class you mentioned and the DbContext class i referred both are parts of the Entity framework itself. The ObjectContext class lives in System.Data.Objects namespace whereas DbContext lives in the System.Data.Entity namespace.
Both ObjectContext and DbContext class provides facilities for querying and working with entity data as objects.
Now, When to use which one :-
Use ObjectContext for version 4.0 when using a designer generated model and DbContext with a 4.1 Code First model. Since you are using designer, I would say you go with ObjectContext.
Once again aplologies for the confusion. Hope, now I have given a better and complete answer

Related

Eager load all properties with Entity Framework

So LazyLoadingEnabled = false apparently doesn't do what I thought it did. And has next to no documentation.
I design my entity trees very carefully. I think hard about every relationship. When I load up an entity that is an Aggregate Root, I want everything that is navigable to from there to load. That's how the Aggregate root concept works after all, if I want something to be weekly related I'd stick an id on the entity and manage the relationship myself.
Is there a way to do this with Entity Framework?
You can try obtaining all NavigationProperties of the element type (in IQueryable). By accessing to the MetadataWorkspace of ObjectContext you can get those properties of a specific type and Include all easily.
Note that I suppose you're using EF5 or later version, whereas DbContext is used. We access to ObjectContext via the interface IObjectContextAdapter. Here is the code:
public static IQueryable<T> LoadAllRelatedObjects<T>(this IQueryable<T> source, DbContext context) {
//obtain the EntityType corresponding to the ElementType first
//then we can get all NavigationProperties of the ElementType
var items = (ObjectItemCollection) ((IObjectContextAdapter)context).ObjectContext.MetadataWorkspace.GetItemCollection(DataSpace.OSpace);
var entityType = items.OfType<EntityType>().Single(e => items.GetClrType(e) == source.ElementType);
return entityType.NavigationProperties
.Aggregate(source, (c, e) => c.Include(e.Name));
}
Note in new version (since EF5), the namespace of ObjectItemCollection (and other metadata items) is System.Data.Entity.Core.Metadata.Edm, while in the old version (before EF5), it's System.Data.Metadata.Emd.
Usage:
yourModel.YourEntities.LoadAllRelatedObjects(yourModel)
//. more query here ...
;
I don't think there's a way to have all of the navigation properties auto-eager load. How about making an extension method instead?
public static IQueryable<Company> LoadCompany(this IQueryable<Company> query) {
return query.Include(x => x.Divisions)
.Include(x => x.Departments)
.Include(x => x.Employees);
}
Example:
var query = from company in db.Companies.LoadCompany()
where company.Name == "Microsoft"
select company;

Updating multiple records using Entity Framework

I am using Entity Framework 5. I am looking for a better approach to update multiple records.
People are talking about EF Extensions. But I am not sure how to use it with my scenario.
This is my method signature.
internal void Update( List<Models.StockItem> stockItemsUpdate)
I need to update all the corresponding stockitem entities.
using (var context = new eCommerceEntities())
{
var items = context.StockItems.Where(si => stockItemsUpdate.Select(it => it.ID).Contains(si.ID));
}
I believe above query will return those entities.
How can I use EF extensions in this scenario?
Thanks.
In EntityFramework.Extended's BatchExtensions there is an Update extension method with this signature:
public static int Update<TEntity>(
this IQueryable<TEntity> source,
Expression<Func<TEntity, TEntity>> updateExpression)
You can use this as follows:
items.Update(item => new StockItem { Stock = 0 });
to set the stock of the selected items to 0.

Entity Framework 4: Access current datacontext in partial entity class

I want to extend an EF entity in a partial class with methods and properties. I've done this quite often.
But now I would need to combine data from this entity with data from other entities. I would therefore need to able to access the entities objectcontext (if attached) to make these queries.
Is there a way to get the entities objectcontext from within it?
Thanx!
There is no build in way to get current ObjectContext from entity. Entities based on EntityObject class and POCO proxies uses ObjecContext internally but they don't expose it.
Adding such depnedency into your entities is considered as bad design so you should perhaps explain what you are trying to do and we can find other (better) solution.
Even though it is not recommended, and I myself don't use it (as Ladislav stated: bad design), I stumbled upon a solution:
http://blogs.msdn.com/b/alexj/archive/2009/06/08/tip-24-how-to-get-the-objectcontext-from-an-entity.aspx
Extension Method:
public static ObjectContext GetContext(
this IEntityWithRelationships entity
)
{
if (entity == null)
throw new ArgumentNullException("entity");
var relationshipManager = entity.RelationshipManager;
var relatedEnd = relationshipManager.GetAllRelatedEnds()
.FirstOrDefault();
if (relatedEnd == null)
throw new Exception("No relationships found");
var query = relatedEnd.CreateSourceQuery() as ObjectQuery;
if (query == null)
throw new Exception("The Entity is Detached");
return query.Context;
}
within the entity
var myContext = this.GetContext() as MyEntities;

Entity Framework Delete All on Submit

In LINQ to SQL, I could do:
context.User_Roles.DeleteAllOnSubmit(context.User_Roles.Where(ur => ur.UserId == user.UserId));
Whats the equivalent to this for entity framework?
foreach(var entity in context.User_Roles.Where(ur => ur.UserId == user.UserId))
{
context.User_Roles.DeleteObject(entity);
}
context.SaveChanges();
Of course, you can write an extension method, which would encapsulate this.
This would be something like this:
public static void DeleteObjects<TEntity> (this ObjectSet<TEntity> set, IEnumerable<TEntity> data) where TEntity : class
{
foreach(var entity in data)
set.DeleteObject(entity);
}
Called like:
context.User_Roles.DeleteObjects(context.User_Roles.Where(ur => ur.UserId == user.UserId))
context.SaveChanges();
#Femaref has the right idea, but for a true analog to L2E's DeleteAllOnSubmit, you'll want your extension method to make a copy of the entities being deleted before enumerating so that you don't get "collection modified while enumerating" exceptions.
public static void DeleteAllObjects<TEntity>(this ObjectSet<TEntity> set, IEnumerable<TEntity> data) where TEntity : class {
foreach(var entity in data.ToList()) //data.ToList() makes a copy of data for safe enumeration
set.DeleteObject(entity);
}
foreach(var entity in context.User_Roles.Where(ur => ur.UserId == user.UserId))
{
context.User_Roles.DeleteObject(entity);
}
context.SaveChanges();
of course, this solution can work. But, it is the most inefficient solution.
This solution will generate one delete SQL command for each record (entity).
Imaging that you want to delete all data before year 2000 . there are more than 1,000,000 records in the database. If delete these objects in this way, more than 1,000,000 SQL commands will be sent to the server, it is a unnecessary big waste.
What
There is no RemoveAll equivalent in Entity Framework, so you can load entities in memory and remove them one by one using DeleteObject method.
You can use Linq : context.MyEntitie.RemoveAll(context.MyEntitie);
use EntityFramework.Extensions
1) First install EntityFramework.Extensions using NuGet
2) Here is the code similar to Linq2Sql's DeleteAllOnSubmit():
using EntityFramework.Extensions;
....
public void DeleteAllUsers(User_Role user){
context.User_Roles.Delete(ur => ur.UserId == user.UserId);
context.SaveChanges();
}
...

Entity Framework deletion of non-null foreign keyed rows

I have a schema similar to the standard Product / OrderDetails / Order setup. I want to delete a single Product and cascade delete all OrderDetails which reference that product.
Assuming that I've thought this through from the business rules perspective, what's the most elegant way to handle that with Entity Framework 4?
First thing is first:
Is there any reason on delete cascade at the database level won't work?
If that's really not a possibility, you could try the following:
Since ObjectContext doesn't have a DeleteAll style method...you could always implement your own:
public static void DeleteAll(this ObjectContext context,
IEnumerable<Object> records)
{
foreach(Object record in records)
{
context.DeleteObject(record);
}
}
Then you could write something like (probably in a Repository):
context.DeleteAll(context.OrderDetails.Where(od => od.Product == product));
Or, to be a little cleaner:
var toDelete = context.OrderDetails.Where(od => od.Product == product);
context.DeleteAll(toDelete);