C# Entity-Framework: How to Combine a .Find and .Include on a Model Object

C# Entity-Framework: How can I combine a .Find and .Include on a Model Object?

You can use Include() first, then retrieve a single object from the resulting query:

Item item = db.Items
.Include(i => i.Category)
.Include(i => i.Brand)
.FirstOrDefault(x => x.ItemId == id);

Using .Find() & .Include() on the same query

I was just thinking about what find actually does. @lazyberezovsky is right include and find cant be used in conjunction with each other. I think this is quite deliberate and here's why:

The Find method on DbSet uses the primary key value to attempt to find
an entity tracked by the context. If the entity is not found in the
context then a query will be sent to the database to find the entity
there. Null is returned if the entity is not found in the context or
in the database.

Find is different from using a query in two significant ways:

  • A round-trip to the database will only be made if the entity with the given key is not found in the context.
  • Find will return entities that are in the Added state. That is, Find will return entities that have been added to the context but have
    not yet been saved to the database.

(from http://msdn.microsoft.com/en-us/data/jj573936.aspx)

Because find is an optimised method it can avoid needing a trip to the server. This is great if you have the entity already tracked, as EF can return it faster.

However if its not just this entity which we are after (eg we want to include some extra data) there is no way of knowing if this data has already been loaded from the server. While EF could probably make this optimisation in conjunction with a join it would be prone to errors as it is making assumptions about the database state.

I imagine that include and find not being able to be used together is a very deliberate decision to ensure data integrity and unnecessary complexity. It is far cleaner and simpler
when you are wanting to do a join to always go to the database to perform that join.

How to include another related object to query using Entity Framework and show it in DataGridView?

public class FacturaDto{
public decimal Total {get;set;}
...
}

public IList<FacturaDto>GetListVentas()
{
return _context.Facturas
.Include(a => a.DetalleFacturas). OrderByDescending(a => a.FechaVenta).Select(x=> new FacturaDto{Total = x.DetalleFacturas.Sum(b => b.PrecioTotal), ...})
.ToList();
}

How to add Entity Model containing a list of another Entity Model type to Database with EF using lambda expressions and linq

you should create new Props when create new unit

like this :

InventoryItemUnit unit = new InventoryItemUnit()
{
Title = model.Title,
Item_Id = model.Item_Id,
                  Props=new List<Props>()
                };

I hope it will be useful

Is it proper form to extend a model object (e.g. Product) and add a Create() method that inserts into the database? (MVC 5 Entity Framework 6)

One of the problems I see is that the entity framework DBContext is a unit of work. if you create a unit of work on Application_BeginRequest when you pass it into controller constructor it acts as a unit of work for the entire request. maybe it's only updating 1 entity in your scenario, but you could be writing more information to your database. unless you are wrapping everything in a TransactionScope, all these Saves are going to be independent which could leave your database in an inconsistent state. And even if you are wrapping everything with a TransactionScope, I'm pretty sure that transaction is going to be promoted to the DTC because you are making multiple physical connections in a single controller and sql server isn't that smart.

Going the BeginRequest route seems like less work than adding methods to all of your entities to save itself. Another issue here is that an EF entity is supposed to be a not really know anything about it's own persistence. That's what the DbContext is for. So putting a reference back to the DbContext breaks this isolation.

Your second reason, adding audit information to the entity, again adding this to each entity is a lot of work. You could override SaveChanges on the context and do it once for every entity. See this SO answer.

By going down this road I think that you are breaking SOLID design principles because your entities violate SRP. introduce a bunch of cohesion and you are ending up writing more code than you need. So i'd advocate against doing it your way.

how to fill Self Reference Table in entity framework core

As the comments said, the OnModelCreating is used to build the relationship between tables.

Before loading the object with parent object, you need to change the code in OnModelCreating. The WithOne need to specific an object.

    public DbSet<Entity>   entities { get; set; }
public DbSet<AppEntity> appEntities { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<AppEntity>(o => {
o.HasIndex(e => e.short_code)
.IsUnique(true);
});
builder.Entity<AppEntity>()
.HasOne(j => j.Parent)
.WithOne(i=>i.appEntity)
.HasForeignKey<AppEntity>(f => f.parent_id);
}

Because you have create the foreign key in dbcontext, so you can remove [ForeignKey("parent_id")].

In addition, in model Entity, you should add the property AppEntity to reference the child object.

 public class Entity
{
public int id { get; set; }

public AppEntity appEntity { get; set; }
}

Then, you can use Include to include the two objects.

    public virtual Entity GetById(int id) 
{

var entity = _context.entities
.Include(y => y.appEntity)
.FirstOrDefault(x => x.id == id);
return entity;
}

Edit:

In one table, this will lead to circular references, because you have added the parent_id to reference the parent.

A better solution is to remove public AppEntity Parent { get; set; }, and remove builder.Entity<AppEntity>().HasOne(j => j.Parent).WithOne().HasForeignKey<AppEntity>(f => f.parent_id);.

Before inserting data into the table, query whether entity_id exists, if it exists, add it, if it does not exist, set it null. Because the primary key has its own index, the query speed is very fast.

When querying, based on these two columns, the corresponding data can be clearly processed using sub-query or associated query.

How to filter nested object when using include Entity Framework core 3.1

I don't remember this working in EF Core at all; and usually we would separate this into two queries: 1- fetch the user data, 2- fetch the filtered user privileges

var user = await RepositoryContext.Users
.FirstOrDefaultAsync(u => u.Id == userId);

await RepositoryContext.UserPrivileges
.Where(up => up.UserId == userId && !up.IsDeleted)
.Include(up => up.Privilege)
.ToListAsync();

return user;

When we bring related data into the context with the 2nd query, ef will take care of populating user.UserPrivileges, so we don't need to assign it at all. This works well if we fetch multiple user data.

Microsoft Entity Framework: List property on Model is not updated in database after adding data and saving

Try to use ICollection<T> instead of List<T> and make PlayerList a property instead of a field by adding { get; set; }

public class Player
{
public long Id { get; set; }

[Required(ErrorMessage = "Player FirstName is required")]
public string FirstName { get; set; }

[Required(ErrorMessage = "Team Name is required")]
public string LastName { get; set; }

public Team Team { get; set; }
}

public class Team
{
public long Id { get; set; }

[Required(ErrorMessage ="Team Name is required")]
public string Name { get; set; }

[Required(ErrorMessage = "Team Location is required")]
public string Location { get; set; }

public ICollection<Player> PlayerList { get; set; }
}

To add a Player to a Team something like that is needed:

var team =  await context.Teams.FindAsync (teamId);
var player = new Player { FirstName = "firstname", LastName = "lastname" };

team.PlayerList.Add (player);
context.SaveChanges ();

You don't need to set the team state to Modified because nothing has changed that needs to be commited to the database. Only the player will be inserted in the database.

EDIT - for your comment on multiple contexts:

It's important that you call context.SaveChanges () on all contexts. Only the instance of context knowns what has been changed and can generate the sql insert/update/delete statements. To make sure that different contexts (or even when you use only one context) will made database changes atomic you can use TransactionScope to make sure either all changes are written to the database or nothing happens at all. Example:

public void DoWork ()
{
// make sure you have MSDTC configured otherwise the TransactionScope will not work.
using (var scope = new TransactionScope ())
{
Action1 ();
Action2 ();

// This will persist it to the database - COMMIT
scope.Complete ();
}
}

public void Action1 ()
{
using (var context = new DbContext ())
{
// Do some work...

context.SaveChanges ();
}
}

public void Action2 ()
{
using (var otherContext = new DbContext ())
{
// Do some work...

otherContext.SaveChanges ();
}
}

Specifying item list contents in Entity Framework with two conditions

Simple. Create a array/list of string of dynamic search keyword and check against it as below:

var conditionarr = new []{"cake","bread","toast","drink"}; // your array or list of string
CartItem Item = Items.Find(c => c.ProductID == ProductID
&& conditionarr.Contains(c.ProductName));


Related Topics



Leave a reply



Submit