EF Code First: How to select data included changes before SaveChanges? - ef-code-first

I can't explain the code. Look at different behavior:
var project = DB.Project.Find(1000111);
project.MustLinkToMF = false;
// Includes id = 1000111; MustLinkToMF = false; - From Cache?
var projects1 = DB.Project.Select(p => p).ToList();
// Doesn't contain 1000111! - Not From Cache?
var projects2 = DB.Project.Where(p => p.MustLinkToMF == false).Select(p => p).ToList();
DB.SaveChanges();
How to get cached data, included my changes?
How Can I get projects2 using one simple query before SaveChanges?
Thank you!

You can navigate through entities in the first level cache:
ctx.ChangeTracker.Entries().Where(x => x.State == EntityState.Modified).Select(x => x.Entity).OfType<T>()
Just replace EntityState.Modified for what you want.
See an example here: https://weblogs.asp.net/ricardoperes/entity-framework-code-first-get-entities-from-local-cache-or-the-database

Related

List in where clause in ASP.net

Hello I am a beginner in ASP.NET
I have a variable checklistsss which was the list of my CheckList. here is the code:
var checkListss = (from u in _userManager.ClearanceCheckListRepository.GetQueryable().Where(x => x.ClearanceId == userId.ClearanceId) select new { clearanceCheckListId = u.ClearanceCheckListId }).ToList();
Now, I want the variable checkListss will put in the where clause at this code:
var due = from checkListsddd in _userManager.DueRepository.GetQueryable().Where(x => x.ClearanceCheckListId == checkListss) select new { Item = checkListsddd.Label, Action = checkListsddd.Action };
to output the due variable in this code
var checkList = from checkLists in _userManager.ClearanceCheckListRepository.GetQueryable().Where(x => x.ClearanceId == userId.ClearanceId) select new { ClearanceSignatoryId = checkLists.ClearanceSignatoryId, ClearanceCheckListId = checkLists.ClearanceCheckListId, Item = checkLists.Item, Action = checkLists.Action, Due = due };
take note that the checkListss will output multiple checkListId
I dont know how to do this in asp.net
thank you for your answers
Without some more details I can only guess at the types but I think what you are missing is using Enumerable.Contains to check if the ID is in checkListss. Something like:
var checkListss = (from u in _userManager.ClearanceCheckListRepository.GetQueryable().Where(x => x.ClearanceId == userId.ClearanceId) select u.ClearanceCheckListId).ToList();
var due = from checkListsddd in _userManager.DueRepository.GetQueryable().Where(x => checkListss.Contains(x.ClearanceCheckListId)) select new { Item = checkListsddd.Label, Action = checkListsddd.Action };
Note that I changed checkListss to be a list of the Id type instead of a list of an anonymous type.
As a side note the mixing of the LINQ fluent and query syntax is a bit confusing to look at (subjectively) so I would stick to the fluent syntax more like:
var checkListss = _userManager.ClearanceCheckListRepository.GetQueryable()
.Where(x => x.ClearanceId == userId.ClearanceId)
.Select(x => ClearanceCheckListId)
.ToList();
var due = _userManager.DueRepository.GetQueryable()
.Where(x => checkListss.Contains(x.ClearanceCheckListId))
.Select(x => new { Item = x.Label, Action = x.Action })
.ToList();

Firestore Pagination query on collection group data

Description: I want to implement infinite scroll in React-Native with firebase and i want to paginate on collection group data for instant result in my app. Error is shown in screenshot.
My code:
var ref = firestore().collectionGroup('user_posts').orderBy('time_stamp', 'desc').limit(5);
ref.get().then(snapshot => {
var posts = []
var lastVisible = snapshot.docs[snapshot.docs.length - 1];
this.setState({ last_Visible: lastVisible });
});
var next = firestore().collectionGroup('user_posts').orderBy('time_stamp', 'desc')
.startAfter(this.state.last_Visible)
.limit(5);
next.get()
.then(FirestoreDocumentSnapshot => {
var lastVisible = FirestoreDocumentSnapshot.docs[FirestoreDocumentSnapshot.docs.length - 1];
this.setState({ last_Visible: lastVisible });
})
Please help, what i am doing wrong?
From a first look at the error and your code it seems like either the fields that you are referring to are empty, or the lastVisible should be an even number.
Try checking that you don't have empty fields in your docs and try removing the -1 from lastVisible.
Here you can check the proper way to use startAfter() which is the cause of your issue.
As you're sorting by time_stamp, you should specify that field in the query like so:
.startAfter(this.state.last_Visible.data().time_stamp)
Here is an example from the official documentation. (From the language tabs choose Node.js)

Multiple request instead of one in EF Core

I have this select which I expected to be executed by sending one command to SQL Server but I can see 10s requests instead. How can I fix it?
We have Companies which have Customers and Orders. For some reasons Orders are under Company entity.
var q = _dbContext.Companies
.Include(x => x.Customers)
.Include(c => c.Orders)
.Where(a => a.CompanyId == 123);
var total = await q.CountAsync();
q = q.OrderByDescending(x => x.CompanyCode)
.Skip((pageIndex - 1) * pageSize).Take(pageSize);
var res = await q.Select(x => new ResultDto()
{
CompanyCode = x.CompanyCode,
Customers = x.Customers
.Where(c => c.IsActive)
.Select(c => new CustomerDto()
{
FirstName = c.FirstName,
Surname = c.Surname,
Orders = x.Orders
.Where(o => o.IsOpen)
.Select(o => new OrderDto()
{
DateCreated = o.DateCreated
}).ToList()
}).FirstOrDefault(),
}).ToListAsync();
This is EF.NetCore optimization.
You actually cant achieve one query when your navigation properties are collections.
I can't find any links right now, but this is by design.
Once you have a collection in your navigations inside select or inside includes it will produce a separate query for each root entity. The reason I believe is the redundant data amount produced by such a query.
I suggest leave it as is if you have not a lot of data < 1000 rows in a result. You will see a lot of queries but they will be really fast.
As I can see you have pagination here so it shouldn't be a problem.
Otherwise, select your collections separately and join them in memory carefully.
Unfortunately, there is no other way for EF Core
Also, I recommend to turn on EF core logs to what is going on early. I bet FirstOrDefault will produce some warning.

How to configure links with HasNavigationPropertiesLink after latest WebAPI beta (26-Jun-2013) Update

I have a basic POCO (No database) structure implementing an OData Service with the latest WebAPI update. Unfortunately, the latest update broke the HasNavigationPropertiesLink code that I had to generate links which can be used for $expand operations. Here is my old code:
var jobs = modelBuilder.EntitySet<Job>("Jobs");
jobs.EntityType.NavigationProperties,
(entityContext, navigationProperty) => new
Uri(entityContext.UrlHelper.Link(ODataRouteNames.PropertyNavigation,
new
{
Controller = "Jobs",
parentId = entityContext.EntityInstance.ID,
NavigationProperty = navigationProperty.Name
})));
And here is my new code (that doesn't work):
var jobs = modelBuilder.EntitySet<Job>("Jobs");
jobs.EntityType.NavigationProperties,
(entityContext, navigationProperty) => new
Uri(entityContext.Url.Link(<??WHAT GOES HERE??>,
new
{
Controller = "Jobs",
parentId = entityContext.EdmObject,
NavigationProperty = navigationProperty.Name
})),
true);
Any help is much appreciated - this doesn't seem to have been documented in the updates.
looks like the version of the OData bits you are using is very old. In our current version, you can use the ODataConventionsModelBuilder to create a model that defines navigation properties and links following conventions, so unless you need to generate custom links, it's a better way to go. However, if you want to generate a custom navigation link, the link generation code looks something similar to this:
var jobs = builder.EntitySet<Job>("Jobs");
jobs.HasNavigationPropertiesLink(customers.EntityType.NavigationProperties,
(context, navigationProperty) =>
{
var result = "http://mydomain.com/prefix/odataPath";
//In order to generate this link you can use context.Url.ODataLink(new EntityPathSegment("Jobs"), ...);
return new Uri(result);
}, followsConventions: true);
it is better to use ODataConventionsModelBuilder as Javier has suggested. But if you still want to set up your own odata model you can do it:
var jobs = builder.EntitySet<Job>("Jobs");
jobs.HasNavigationPropertiesLink(customers.EntityType.NavigationProperties,
(context, navigationProperty) => context.GenerateNavigationPropertyLink(navigationProperty, false)
, followsConventions: true);

Update table with LINQ

SOLVED look below code snippet.
I have a problem with updating tables, The code shows no faults but it don't act as expected, it does not put any information in the Log Table.
some explenation, i have a table called User with a FK on LogID and a table called Log with PK on LogID so that should be correct, the Log has a column called TimesLoggedIn and one called LastLogedin. and i want to update them accordingly.
User logid = db.Users.Single(p => p.UserID == loginID);
logid.Log.LastLogedin= DateTime.UtcNow;
if (logid.Log.TimesLoggedIn == null)
{
logid.Log.TimesLoggedIn = 1;
}
else
{
logid.Log.TimesLoggedIn = logid.Log.TimesLoggedIn + 1;
}
db.SubmitChanges();
had an embarrassing fault in my code, i had
Response.Redirect("ControlPanel");
placed before i ran the LINQ not after.
I'm using Entity Framework, so I might be wrong. But maybe the Log isn't loaded at all.
Try this:
var options = New DataLoadOptions();
options.LoadWith<Users>(x => x.Log);
db.LoadOptions = options;
// then your code:
User logid = db.Users.Single(p => p.UserID == loginID);
logid.Log.LastLogedin= DateTime.UtcNow;
....

Resources