EF CORE Power Tools DbContextExtensions ambiguity - asp.net-core

I use the EF CORE Power Tool to generate database classes in two separate .Net class library projects. A third WebAPI project references these libraries. The compilation succeeds when only one stored procedure is included in one of the libraries. I get following error when a second stored procedure is included in the other library. I think there are two identical DbContextExtensions that cause this problem. How to solve this ambiguity? Thanks.
The call is ambiguous between the following methods or properties: 'IPRehabModel.DbContextExtensions.SqlQueryAsync
(Microsoft.EntityFrameworkCore.DbContext, string, object[], System.Threading.CancellationToken)' and 'UserModel.DbContextExtensions.SqlQueryAsync
(Microsoft.EntityFrameworkCore.DbContext, string, object[], System.Threading.CancellationToken)' IPRehabWebAPI2 C:\Users\xxx\yyy\repos\theApp\IPRehabWebAPI2\Helpers\UserPatientCacheHelper.cs 58 Active
Here is the code for that contains the error
public async Task <List<MastUserDTO>> GetUserAccessLevels(string networkID) {
string userName = CleanUserName(networkID); //use network ID without domain
SqlParameter[] paramNetworkID = new SqlParameter[] {
new SqlParameter() {
ParameterName = "#UserName",
SqlDbType = System.Data.SqlDbType.VarChar,
Direction = System.Data.ParameterDirection.Input,
Value = userName
}
};
/*line58*/
var userPermission = await
_context.SqlQueryAsync <theStoredProcedureResult> (
$ "execute [Apps].[theStoredProcName] #UserName", paramNetworkID);
var distinctFacilities = userPermission
.Where(x => !string.IsNullOrEmpty(x.Facility)).Distinct()
.Select(x => HydrateDTO.HydrateUser(x)).ToList();
return distinctFacilities;
}

Related

Get and manipulate data from elasticsearch

I am new to elasticsearch so I will need some help. Unfortunately, I didnt found the answer in other topics here on SO.
I have some .net core application which I inherited and now there is a need to implement some changes.
I already have a method of getting data from elasticsearch, but after getting them, I am not sure how to change it and use it in application.
To be precise, I need to parse first and last name and to remove special characters, specific serbian latin letters like "šđžčć" etc... I already have a method for this parsing written but not sure how to call it...
So, my question is can I and how can I do this?
What I have now is the following:
var result = await _elasticClient.SearchAsync<CachedUserEntity>(
s =>
s.Index(_aliasName)
.Query(q => andQuery));
CachedUserEntity, among others, contains property about FirstName and LastName.
Inside results.Documents, I am getting the data about FirstName and LastName from elasticsearch, but I am not sure how to access it in order to update it via aformentioned NameParser ...
Sorry if the question is too easy, not to say stupid :)
I wont use updateByQuery here, for some reasons. I would scroll on documents (i use matchAll on my exemple, you obviously need to replace it with your query), or, if you dont know how to identify documents to update, only update usefull documents in UpdateManyWithIndex/UpdateManyPartial function.
For performance, we have to update severals documents at once, so we use bulk/updateMany function.
You can use both solution, the classic update, or the second (partial update) with an object containing the targeteds fields.
On server sides, both solutions will have the same cost / performance.
var searchResponse = Client.Search<CachedUserEntity>(s => s
.Query(q => q
MatchAll()
)
.Scroll("10s")
);
while (searchResponse.Documents.Any())
{
List<CachedUserEntity> NewSearchResponse = RemoveChar(searchResponse);
UpdateManyWithIndex<CachedUserEntity>(NewSearchResponse, _aliasName);
searchResponse = Client.Scroll<Project>("2h", searchResponse.ScrollId);
}
public void UpdateManyWithIndex<C>(List<C> obj, string index) where C : class {
var bulkResponse = Client.Bulk(b => b
.Index(index).Refresh(Elasticsearch.Net.Refresh.WaitFor) // explicitly provide index name
.UpdateMany<C>(obj, (bu, d) => bu.Doc(d)));
}
Or, using partial update object
Note: in this case Indix is already set on my client (add .index if needed)
var searchResponse = Client.Search<CachedUserEntity>(s => s
.Query(q => q
MatchAll()
)
.Scroll("2h")
);
while (searchResponse.Documents.Any())
{
List<object> listPocoPartialObj = GetPocoPartialObjList(searchResponse);
UpdateManyPartial(listPocoPartialObj);
searchResponse = Client.Scroll<Project>("2h", searchResponse.ScrollId);
}
private List<object> GetPocoPartialObjList(List<CachedUserEntity> cachedList) {
List<object> listPoco = new List<object>();
//note if you dont have cachedList.Id, take a look at result.source, comments if needed
foreach (var eltCached in cachedList) {
listPoco.Add( new object() { Id = cachedList.Id, FirstName = YOURFIELDWITHOUTSPECIALCHAR, LastName = YOURSECONDFIELDWITHOUTSPECIALCHAR});
}
return listPoco;
}
public bool UpdateManyPartial(List<object> partialObj)
{
var bulkResponse = Client.Bulk(b => b
.Refresh(Elasticsearch.Net.Refresh.WaitFor)
.UpdateMany(partialObj, (bu, d) => bu.Doc(d))
);
if (!bulkResponse.IsValid)
{
GetErrorMsgs(bulkResponse);
}
return (bulkResponse?.IsValid == true);
}

How to run normally query script in entity framework mvc c#

I have face problem about entity framework in mcv c#,
i decide to change the way to exec query to normally query scripting,
this bellow script I have for exemple
//for only one row result
string activeUser = await db.Users.Where(x => x.Token.Equals(token)).Select(x => x.Username).FirstOrDefaultAsync();
ReceivingSFG receiving = await db.ReceivingSFGs.Where(s => s.ID.Equals(receivingVM.ID)).FirstOrDefaultAsync();
//for multiple row result (List)
IQueryable<ReceivingSFGDetail> query = db.ReceivingSFGDetails.Where(s => s.ReceivingID.Equals(req.ID)).AsQueryable();
IEnumerable<ReceivingSFGDetail> list = Enumerable.Empty<ReceivingSFGDetail>();
list = query.ToList();
IEnumerable<ReceivingSFGDetailDTO> listDto = Enumerable.Empty<ReceivingSFGDetailDTO>();
string message = "";
bool status = false;
listDto = from x in list
select new ReceivingSFGDetailDTO
{
ID = x.ID,
ReceivingID = x.ReceivingID,
Barcode = x.Barcode,
QtyActual = x.QtyActual,
QtyBag = x.QtyBag,
CreatedBy = x.CreatedBy,
CreatedDate = x.CreatedDate,
QtyPerBag = x.QtyPerBag
};
or some case that I never use before,
like how to exec store procedure... please some one can help me to solve this case.
If you want to execute Stored Procedure vie Entity framework you will of course have to start by mapping it into the data context.
Once the stored procedure is mapped in your model layer you can simply call it pseudo like this:
List<SomeStuff_Result> list = _db.NameOfStoredProcedure(string somevariable).ToList();
It should behave the same way any object you receive from data layer.
You can also check this answer.

How can I call stored procedure result into view model asp.net core

How can I call the stored procedure into view model
SqlParameter paruserID = new SqlParameter("#UserID", userId);
SqlParameter paryear = new SqlParameter("#LogYear", lockyear);
SqlParameter parmonth = new SqlParameter("#LogMonth", lockmonth);
var result = _db.Database.SqlQuery<AttendanceViewModel>("EmpProcedure", paruserID ,paryear ,parmonth
The Database.SqlQuery method is not provided in EF Core. If you'd like to execute a stored procedure, you can try to use the FromSqlRaw extension method, like below.
var result = _db.Attendance.FromSqlRaw("EXEC EmpProcedure #UserID, #LogYear, #LogMonth", parameters)
.ToList()
.Select(u => new AttendanceViewModel
{
UserID = u.UserID,
LogYear = u.LogYear,
LogMonth = u.LogMonth
//other fields
//...
}).FirstOrDefault();
For more information about executing Raw SQL Queries, you can check following doc:
https://learn.microsoft.com/en-us/ef/core/querying/raw-sql
Besides, the DbContext.Database property provides an API that allows us to perform ADO.NET operations directly, you can also use following code snippet to execute your stored procedure.
using (var command = _db.Database.GetDbConnection().CreateCommand())
{
command.CommandType = System.Data.CommandType.StoredProcedure;
command.CommandText = "EmpProcedure";
command.Parameters.Add(new SqlParameter("#UserID", userId));
command.Parameters.Add(new SqlParameter("#LogYear", lockyear));
command.Parameters.Add(new SqlParameter("#LogMonth", lockmonth));
_db.Database.OpenConnection();
using (var reader = command.ExecuteReader())
{
// ...
// code logic here
// do something based on your actual requirement
}
}
For more information about leveraging ADO.NET via the Context.Database property, please check:
https://www.learnentityframeworkcore.com/raw-sql#leveraging-ado.net-via-the-context.database-property

How to get entity collection from context in code dynamically?

Suppose I have 2 tables : tab1, tab2, with EF and Wcf Ria service, there are 2 entity Tab1, Tab2 available at client side of domaincontext.
Then I want to get the entityset dynamically in code, like
MyDomainContext.Entities("Tab1");
How can I do this?
In your client side code you will have a reference, such as:
using System.ServiceModel.DomainServices.Client;
Then you would load collections of your entities like so:
var ctx = new MyDomainContext();
ctx.Load<tab1>( _ctx.GetTab1Query(), LoadBehavior.RefreshCurrent, (op) =>
{
var data = op.Entities;
} , null );
In the above code snippet your server side domain service has provided you with the GetTab1Query.
I've seen this in Kyle McClellan's code in his ComboBoxDataSource. He takes a string parameter and calls an Operation (or Query). This is now part of the RiaServicesContrib project in the ComboBoxDataSource module.
The essentials (from ComboBoxDataSource.cs, Refresh method):
Type domainContextType = this.DomainContext.GetType();
MethodInfo operationInfo = domainContextType.GetMethods().Where(
m => (m.Name == this.OperationName) && (m.GetParameters().Count() == this.Parameters.Count)).FirstOrDefault();
this.Operation = (InvokeOperation)operationInfo.Invoke(this.DomainContext, this.Parameters.Select(p => p.Value).ToArray());
this.Operation.Completed += this.OnInvokeCompleted;

Strange "Expected invocation on the mock at least once, but was never performed" error when I am setting up the Mock

I'm getting this error from Moq via NUnit, and it doesn't make much in the way of sense to me.
"Expected invocation on the mock at least once, but was never performed: x => x.DeleteItem(.$VB$Local_item)"
"at Moq.Mock.ThrowVerifyException(MethodCall expected, IEnumerable1 setups, IEnumerable1 actualCalls, Expression expression, Times times, Int32 callCount)
at Moq.Mock.VerifyCalls(Interceptor targetInterceptor, MethodCall expected, Expression expression, Times times)
at Moq.Mock.Verify[T](Mock mock, Expression1 expression, Times times, String failMessage)
at Moq.Mock1.Verify(Expression`1 expression)
at PeekABookEditor.UnitTests.ItemBrowsing.Can_Delete_Item() in C:\Projects\MyProject\MyProject.UnitTests\Tests\ItemBrowsing.vb:line 167"
Very similar code works well in C#, so the error might be minor and syntactical on my part.
Here's my code:
<Test()> _
Public Sub Can_Delete_Item()
'Arrange: Given a repository containing some item...
Dim mockRepository = New Mock(Of IItemsRepository)()
Dim item As New Item With {.ItemID = "24", .Title = "i24"}
mockRepository.Setup(Function(x) x.Items).Returns(New Item() {item}.AsQueryable())
'Act ... when the user tries to delete that product
Dim controller = New ItemsController(mockRepository.Object)
Dim result = controller.Delete(24)
'Assert ... then it's deleted, and the user sees a confirmation
mockRepository.Verify(Sub(x) x.DeleteItem(item))
result.ShouldBeRedirectionTo(New With {Key .action = "List"})
Assert.AreEqual(DirectCast(controller.TempData("message"), String), "i24 was deleted")
End Sub
The guilty line appears to be "mockRepository.Verify(Sub(x) x.DeleteItem(item))"
Any thoughts on how to fix this?
Working C# code isn't the exact same, but here it is:
[Test]
public void Can_Delete_Product()
{
// Arrange: Given a repository containing some product...
var mockRepository = new Mock<IProductsRepository>();
var product = new Product { ProductID = 24, Name = "P24"};
mockRepository.Setup(x => x.Products).Returns(
new[] { product }.AsQueryable()
);
// Act: ... when the user tries to delete that product
var controller = new AdminController(mockRepository.Object);
var result = controller.Delete(24);
// Assert: ... then it's deleted, and the user sees a confirmation
mockRepository.Verify(x => x.DeleteProduct(product));
result.ShouldBeRedirectionTo(new { action = "Index" });
controller.TempData["message"].ShouldEqual("P24 was deleted");
}
In your VB test method, you create Item with a string ItemID = "24", but you call the controller.Delete method with an integer value of 24.
Check your controller code and see if the type discrepancy results in the item not being identified correctly, so either DeleteItem is not called at all, or is called with a different Item.