I have created the following code which generates a JSON of the changes that have been made using Audit.net and Audit.EntityFramework.Core;
AuditNet.Configuration.Setup()
.UseEntityFramework(_ => _
.AuditTypeMapper(t => typeof(AuditLog))
.AuditEntityAction<AuditLog>((ev, entry, entity) =>
{
entity.AuditData = entry.ToJson();
entity.EntityType = entry.EntityType.Name;
entity.AuditAction = entry.Action;
entity.AuditDate = DateTime.Now;
entity.AuditUser = Environment.UserName;
entity.TablePk = entry.PrimaryKey.First().Value.ToString();
})
.IgnoreMatchedProperties(true));
AuditNet.Configuration.Setup()
.UseFileLogProvider(config => config
.FilenamePrefix("Event_")
.Directory(#"C:\Users\Cristian Reche\source\repos\people-back"))
.WithCreationPolicy(EventCreationPolicy.InsertOnStartReplaceOnEnd)
.WithAction(x => x.OnScopeCreated(scope => scope.SetCustomField("ApplicationId", "Pepople-Back Auditoria")));
But I need to insert that data into my database. It's possible?
You should call Audit.Core.Configuration.Setup() only once. Otherwise the second call will override the configuration.
Related
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();
When I try to use selectMany on queryable that I build against cosmosdb I always get exception:
The LINQ expression 'DbSet
.Where(t => t.Id == __timelineId_0)
.SelectMany(
source: t => EF.Property>(t, "GraduationEvents")
.AsQueryable(),
collectionSelector: (t, c) => new TransparentIdentifier(
Outer = t,
Inner = c
))' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
The query doesn't matter, always when I use selectMany I get this error.
Example query:
await _dbContext.Timelines.Where(x => x.Id == timelineId).Select(x => x.GraduationEvents).SelectMany(x => x).ToListAsync();
My entity configuration:
public void Configure(EntityTypeBuilder<Timeline> builder)
{
builder.HasKey(x => x.Id);
builder.HasAlternateKey(x => x.Id);
builder.OwnsMany(x => x.GraduationEvents, x => x.OwnsMany(graduationEvent => graduationEvent.Subjects));
}
I also tried to use native cosmosClient but when I query the base with plain sql I get empty objects (all nulls). Any thoughts what am I doing wrong?
Sajid - I tried your soulution but the exception remains the same
Try calling directly .SelectMany() over the List property (GraduationEvents).
I usually then call AsDocumentQuery() to generate the query to CosmosDB and then execute that query to retrieve the results.
Some pseudo c# to clarify this a bit:
var query = this.documentClient.CreateDocumentQuery(uri, options)
.SelectMany(x => x.GraduationEvents).AsDocumentQuery();
List<T> results = new List<T>();
while (query.HasMoreResults)
{
results.AddRange(await query.ExecuteNextAsync());
}
Edit: This approach uses the native Azure DocumentClient library.
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.
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
I'm passing a string to a controller, and need the controller to search for ANY of the words passed, within the Title field of my database.
eg. id="outlook error message"
[HttpPost]
public JsonResult Lookup(string id)
{
List<string> listOfSearch = id.Split(' ').ToList();
var results = db.KS.Where(x => x.Title.Intersect(listOfSearch).Any());
This produces the following two errors:
Instance argument: cannot convert from 'string' to 'System.Linq.IQueryable<string>
'string' does not contain a definition for 'Intersect' and the best extension method overload 'System.Linq.Queryable.Intersect<TSource>(System.Linq.IQueryable<TSource>, System.Collections.Generic.IEnumerable<TSource>)' has some invalid arguments
Can anyone please advise what's wrong, or how to populate results with just a list of Titles that contain any of the words passed in?
Thanks, Mark
var results = db.KS.Where(x => listOfSearch.Any(item => x.Title.Contains(item)));
Update:
For LinqToSql:
var titles = db.KS.Select(item => item.Title)
.AsEnumerable()
.Where(title => listOfSearch.Any(word => title.Contains(word)));
you can try
List<string> listOfSearch = id.Split(' ').ToList();
var result = from item in db.KS
where listOfSearch.Any(v => item.Title.Contains(v))
select item;
or
var result = db.KS.Where(item => listOfSearch.Any(v => item.Title.Contains(v)));
Change the statement to:
db.KS.Intersect(....
KS returns you the IQueryable on which you can directly perform the intersection.