Insert audit.net data into database - audit.net

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

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();

SelectMany doesn't work on cosmosDb for child properties?

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.

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.

EF Code First: How to select data included changes before SaveChanges?

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

Search for any word in a Linq query

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.

Resources