I have 2 ways to use a model generated by Entity Framework. I can not find which to use when and why.
Method 1
ODataQueryOptions<Key_Result> options (Passed as function argument)
private ODataQuerySettings settings = new ODataQuerySettings();
IQueryable<Key_Result> result;
try
{
result = options.ApplyTo(DataAccessFunction.Key(keyIds), settings) as IQueryable<Key_Result>;
}
Method 2
IQueryable<Log> result;
try
{
result = AccessModel.Log;
}
So far, I have used them in my code without knowing what is correct or why both are even used. I can't find any material to help me too.
Also, the first one I am using in Odata endpoints created using the table valued functions in sql while the second one I am using with endpoints created using simple tables and views.
But if Entity framework is consistent, it shouldn't matter. And I should be able to use the two approaches interchangeably. Can they be used interchangeably, what is the difference which makes them preferred for one situation (Table valued function) and not preferred for the other one (Tables, views).
Both can be used but both have different uses. If my settings parameters such as null propagation, stable sort or page size have to be set I could use method 1.
However, setting page size etc. could also be done without this. Method 2 is the simplest but does not handle any page sizing or null propagation etc.
Related
How do i do this the proper way legit code. like if it do a linq query within using and the result is i want it to use on another different bracket of using another call of linq query
if i store it i could declare a pre define var neither can i use a class constructor method.
what is the proper way to do this that i may able to use it on maybe different modules or different function / method without again doing the same call over in every method.
Hope i made it clear what i want.
var globalstorage;
using (Si360DbContext _si360DbContext = new Si360DbContext())
{
var selectedItems = _si360DbContext.SaleDumpDetails
.Where(sd => sd.SaleID == saleid)
.Select(i => i.SaleItemID).ToList();
//Store data..
globalstorage = selectedItems;
}
// able to reuse it else where having the same data stored on it.
globalstorage
It depends... as always...
If you're working on a web project, some mechanism that allows you to cache would be approprate. A MemoryCache for example could be a good and fast solution. However... If the amount of data grows, or you run multiple instances of the same website for example, you may need a distributed cache system like Redis.
For different types of apps, console or maybe Windows desktop you could just create a public static variable and you're good to go. So again, it totally depends on the needs of your solution.
I've been using Microsoft.AspNetCore.Mvc.ResponseCacheAttribute for the first time and have come across an issue that I would have solved previously using the VaryByCustom property in OutputCachein ASP.NET (and using public override string GetVaryByCustomString(HttpContext context, string s) in the global.asax).
This VaryByCustom caching seems to no longer exist in ASP.NET Core. Is there a built-in alternative that I'm missing here or will I need to implement this myself to achieve something similar?
From my understanding, you have two flexible options in ASP.NET core:
Use the VaryByHeader or VaryByQueryKeys if you're using the ResponseCacheAttribute.
When using Headers, you need to write the value to vary by as a header, which could be any arbitrary value (no need to expose data to the client):
Response.Headers.Add("X-My-Vary-Header", "this-is-variable");
In essence, this is all the VaryByCustomString ever did for you anyway. The way I see it, you're no longer forced to put this code in a specific method/file (e.g. global.asax).
Try the <cache> Tag Helper when caching in Razor.
Here you have a wide range of things to "vary" by: vary-by-header, vary-by-route, vary-by-user, and even a custom vary-by.
Have a look here and decide whether to use the attribute or the cache tag helper: https://learn.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/built-in/cache-tag-helper
I've looked through the source and I'm not finding anything (although I'm not great at IL), but I would like see if there is a way to provide Dapper a class instance instead of it always instantiating a new one. The reason for this is we may sometimes make two separate calls to two different stored procedures - one returns some columns of an 'entity', the other returns other columns. However, instead of the second query using the entity we received in the first call, we instead get two instances of essentially the same entity. It would be much more preferable for Dapper to use the existing entity class and map the query results to that existing class.
Is there any way to intercept Dapper's class instantiation so as to provide it with an existing instance if needed?
Excellent question. At the moment, it allows you to indicate a particular constructor, but it always news:
il.Emit(OpCodes.Newobj, specializedConstructor);
What we could do is make it possible to specify either a constructor or a static factory method; I suspect this would be just a three-line change to the core materializer code, plus a few other places. Not impossible, but then it gets into questions like calling-context: how does dapper provide caller-specified context to the factory. Again: all possible (protobuf-net does pretty much the same thing).
But none of that exists today. It wouldn't be impossible.
I'm using v2.0 of the API via the C# dll. But this problem also happens when I pass a Query String to the v2.0 API via https://rally1.rallydev.com/slm/doc/webservice/
I'm querying at the Artifact level because I need both Defects and Stories. I tried to see what kind of query string the Rally front end is using, and it passes custom fields and built-in fields to the artifact query. I am doing the same thing, but am not finding any luck getting it to work.
I need to be able to filter out the released items from my query. Furthermore, I also need to sort by the custom c_ReleaseType field as well as the built-in DragAndDropRank field. I'm guessing this is a problem because those built-in fields are not actually on the Artifact object, but why would the custom fields work? They're not on the Artifact object either. It might just be a problem I'm not able to guess at hidden in the API. If I can query these objects based on custom fields, I would expect the ability would exist to query them by built-in fields as well, even if those fields don't exist on the Ancestor object.
For the sake of the example, I am leaving out a bunch of the setup code... and only leaving in the code that causes the issues.
var request = new Request("Artifact");
request.Order = "DragAndDropRank";
//"Could not read: could not read all instances of class com.f4tech.slm.domain.Artifact"
When I comment the Order by DragAndDropRank line, it works.
var request = new Request("Artifact");
request.Query = (new Query("c_SomeCustomField", Query.Operator.Equals, "somevalue").
And(new Query("Release", Query.Operator.Equals, "null")));
//"Could not read: could not read all instances of class com.f4tech.slm.domain.Artifact"
When I take the Release part out of the query, it works.
var request = new Request("Artifact");
request.Query = (((new Query("TypeDefOid", Query.Operator.Equals, "someID").
And(new Query("c_SomeCustomField", Query.Operator.Equals, "somevalue"))).
And(new Query("DirectChildrenCount", Query.Operator.Equals, "0"))));
//"Could not read: could not read all instances of class com.f4tech.slm.domain.Artifact"
When I take the DirectChildrenCount part out of the query, it works.
Here's an example of the problem demonstrated by an API call.
https://rally1.rallydev.com/slm/webservice/v2.0/artifact?query=(c_KanbanState%20%3D%20%22Backlog%22)&order=DragAndDropRank&start=1&pagesize=20
When I remove the Order by DragAndDropRank querystring, it works.
I think most of your trouble is due to the fact that in order to use the Artifact endpoint you need to specify a types parameter so it knows which artifact sub classes to include.
Simply adding that to your example WSAPI query above causes it to return successfully:
https://rally1.rallydev.com/slm/webservice/v2.0/artifact?query=(c_KanbanState = "Backlog")&order=DragAndDropRank&start=1&pagesize=20&types=hierarchicalrequirement,defect
However I'm not tally sure if the C# API allows you to encode additional custom parameters onto the request...
Your question already contains the answer.
UserStory (HierarchicalRequirement in WS API) and Defect inherit some of their fields from Artifact, e.g. FormattedID, Name, Description, LastUpdateDate, etc. You may use those fields in the context of Artifact type.
The fields that you are trying to access on Artifact object do not exist on it. They exist on a child level, e.g. DragAndDropRank, Release, Iteration. It is not possible to use those fields in the context of Artifact type.
Parent objects don't have access to attributes specific to child object.
Artifact is an abstract type.
If you need to filter by Release, you need to make two separate requests - one for stories, the other for defects.
We inherited some C# code as part of a project from another company which does URL redirects that modifies the existing query string, changing values of items, adding new params, etc as needed. The issue however is that the code is buggy at best, and ends up duplicating items in the query string instead of updating them properly. The code works on the first pass but on additional calls the duplication issues become apparent.
Ex: MyPage.aspx?startdate=08/22/09&startdate=09/22/09
Instead of duplicating the item it needs to be either updated with the new value if it already exists, or added if not there already.
Is there a C# class or set of functions for handling query strings, allowing a simple means to access and update/add parameters that gets around these issues instead of the blind add approach that seems to be in use now with the code? This needs to be able to handle multiple parameters that may or may not exists at all times and be added and updated on subsequent calls.
We would sooner use existing logic than recreate something if possible so as to get this resolved quickly in a semi standard way for future maintainability and reuse.
Yes I would suggest converting the querystring to a collection by using HttpUtility.ParseQueryString()
You can then find/add/update/replace values directly in the collection, before re-creating the querystring from this collection.
This should make it easier to spot duplicates.
You can access and manipulate all values of your Querystring through the Request.QueryString collection. Here's a link.
this seems a basic design problem.
instead of updating the current query string, what SHOULD be done is simply adding all the parameters to the base at every time.
sure, you CAN update it, but (pseudocode)
if querystring exists
then update query string
else
add query string
will get crazy when you start using more than 1 variable.
redesign would be best, effort allowing.
The WCF REST Starter Kit available on ASP.NET also include a new "HttpQueryString" helper class that will most likely be included in the .NET 4.0 time frame into the base class library.
See an excellent screencast on how to use this utility class here:
http://channel9.msdn.com/shows/Endpoint/endpointtv-Screencast-HttpClient-Query-String-and-Form-Input-Management/
Marc