How to get inserted row ID with WebMatrix - asp.net

There is a GetLastInsertId method in WebMatrix. However, using Reflector, I can see that it's implemented like this:
[return: Dynamic]
public object GetLastInsertId()
{
return this.QueryValue("SELECT ##Identity", new object[0]);
}
Which, as far as I can see, is a very bad way of doing it, because ##Identity returns the last insert considering every table and every session. I need this restricted to the scope and session I'm working with, so I was expecting this to use SELECT SCOPE_IDENTITY(), since that also seems to be what is most often used according to my reading.
My questions are:
Do the WebMatrix wrappers do something that makes this ok to use in my case?
If not, is there a simple way to get the inserted ID of an insert query using WebMatrix classes, or should I fall back on stuff like SqlClient for this?
I am interested in answers for SQL Server (not compact) if that makes a difference.

I had the same problem, and I read these answers but still couldn't get the code to work correctly. I possibly was misreading the solutions above, but what seemed to work for me was as follows:
var db=Database.Open(...);
var lastInsertID = db.QueryValue("INSERT name into Names; SELECT SCOPE_IDENTITY()");

To quote David Fowler, one of the devs on the Data APIs in WebMatrix: "[SCOPE_IDENITTY] doesn't work on ce". Since we wanted a data API that would work on both CE and regular SQL Server, we used ##Identity. So if you want to use SCOPE_IDENTITY specifically, you should use db.QueryValue method:
var db = Database.Open(...);
db.Insert(...);
var lastInsertId = db.QueryValue("SELECT SCOPE_IDENTITY()")

here is my solution
var db.Database.open('..');
var lastId = db.GetLastInsertId();

Related

Getting ProjectBOs from CatalogCategoryBO returns different results based on BusinessObjectRepositoryContext

We are trying to get all ProductBOs from CatalogCategoryBO with following code:
final CatalogBORepository catalogBORepository = applicationBO.getRepository("CatalogBORepository");
final CatalogCategoryBO catalogCategoryBO = catalogBORepository.getCatalogBOByCatalogName(catalogName).getCatalogCategoryBOByName(catalogCategoryName);
final CatalogCategoryBOCommonProductAssignmentExtension assignmentExtension = catalogCategoryBO.getExtension(CatalogCategoryBOCommonProductAssignmentExtension.class);
return assignmentExtension.getSortedProducts(applicationBO.getDefaultLocale());
But this does not always work as expected. After debugging I found out that main reason is BusinessObjectRepositoryContext:
((BusinessObjectRepositoryContext)catalogCategoryBO.getContext().getVariable("CurrentBusinessObjectRepositoryContext");
which is different based on location from which we call given method (organization or channel).
The same problem is described here: https://support.intershop.com/kb/index.php/Display/IS-22604
Is there some workaround or better way to get all assigned ProductBOs from CatalogCategoryBO?
We are using Intershop B2C version 7.9.1.2.
One possibility is to call pipeline for getting products as suggested by Willem Evertse, another one is to fetch CatalogBORepository and CatalogCategoryBO within block of:
try (ApplicationContext applicationContext = application.forceApplicationContext()) {
// your code here
}
https://support.intershop.com/kb/index.php/Display/2X3516#Concept-ApplicationFramework-TheExecutionContextofanApplication
Yes, this is because the business objects can have different implementations depending on the context (application).
If you look at how the rest api does it (see ProductListResource) they call the ProductHandler (see ProductHandlerImpl) method:
getProducts(Domain currentChannel, CatalogCategoryBO category, String searchTerm, String localeId,...)
Only the category parameter is mandatory it seems, the other parameters can be null. The added benefit is that this code will call the Solr index (if u have it enabled) so it should perform better than running a query on the database (which is also a possibility).

Dealing with numbers using Spring ExampleMatcher

I am new to Java and Spring, and I am building a sytem using Spring JPA. I am now working on my service and controller classes, and I would like to create a dynamic query. I have created a form, in which the user can enter values in the fields, or leave them blank. I then use example matcher to create an example based on non null fields and query objects in the database that match non null fields of the object.
It is working fine with Strings, and it works ok with numbers, in case the number entered by the user is matching the number in the database. What I would like to ask the community is: how can we, using Spring ExampleMatcher, add logic so that the query relating to numbers is not Select * from Projects where project.return = 10 but for instance Select * from Projects where project.return >=10?
It is a pretty basic question, but I have looked everywhere on the web, and I could not find an answer. All sources that I found said that ExampleMatcher deals only with Strings, but I find that strange that such a powerful system does not have a logic to deal with higherthan / lowerthan number type of criteria.
My code for the example matcher:
ExampleMatcher matcher = ExampleMatcher.matching()
.withIgnoreNullValues()
.withIgnoreCase()
.withIgnorePaths("projectId", "businessPlans", "projectReturn", "projectAddress.addressId")
I would like to add something like:
.withMatcher("projectAmountRaised", IsMoreThan(Long.parseLong()));
What I would have loved to have, but it is deprecated:
public static List getStockDailyRecordCriteria(Date startDate,Date endDate,
Long volume,Session session){
Criteria criteria = session.createCriteria(StockDailyRecord.class);
if(startDate!=null){
criteria.add(Expression.ge("date",startDate));
}
if(endDate!=null){
criteria.add(Expression.le("date",endDate));
}
if(volume!=null){
criteria.add(Expression.ge("volume",volume));
}
criteria.addOrder(Order.asc("date"));
return criteria.list();
}
I am thus looking for something similar... I could create a broad results list from just Strings criteria using ExampleMatcher, and then write my own logic to delete objects that do not fit number criteria, but I am sure there is a more elegant approach.
Thank you a lot for your help, and for your indulgence!
This is how you can use QBE and pageable with additional filters:
ExampleMatcher matcher = UntypedExampleMatcher.matching()
.withIgnoreCase()
.withIgnorePaths("startDate");
MyDao probe = new MyDao()
final Example<MyDao> example = Example.of(probe, matcher);
Query q = new Query(new Criteria().alike(example)).with(pageable);
q.addCriteria(Criteria.where("startDate").gte(probe.getStartDate()));
List<MyDao> list = mongoTemplate.find(q, example.getProbeType(), "COLLECTION_NAME");
PageableExecutionUtils.getPage(list, pageable, () -> mongoTemplate.count(q, example.getProbeType(), "COLLECTION_NAME"));

Preparedquery vulnerable to Sql injection

I am running OWASP Zap as a security review for our code.
A SQL injection is being detected when we are using preparedquery and I am struggling to determine why? The basis of our code is:
DLPreparedQuery preparedQuery = this._env.Conn.Prepare("select a from Table1",
new DLDataTypes[] { DLDataTypes.BigInt, DLDataTypes.Char, DLDataTypes.BigInt, DLDataTypes.BigInt, DLDataTypes.Char, DLDataTypes.BigInt },
new string[] { "#P1", "#P2", "#P3", "#P4", "#P5", "#P6" },
DLQueryOptions.Default, -1);
object[,] objResult = (object[,])preparedQuery.Query(1, 'ABC', 'DEF', 1,'AAA',21);
We also escape all user input text with antixss using
Microsoft.Security.Application.Encoder.HtmlEncode(inputData)
Are there settings I should be looking at at SQLServer?
Thanks in Advance.
Haven’t worked with preparedquery but I’d suggest you run sql profiler until you identify the malicious statement. After identifying how statement looks like, you’ll most probably know what to do.
HtmlEncode doesn’t work here. I’d suggest you try replacing single quote ‘ with two single quotes. This is not a bullet proof solution but it’s likely to give you good results.
If your database is in full recovery mode you can try using some third party transaction log reader to scan through already executed statements and try to identify what could be the issue.

Linq returning wrong value from DB

I have a super simple select in a wcf service like
BusinessModel.Candidate candidateObject
= dcMUPView.Candidates.SingleOrDefault(dev => dev.Username == username);
But when I hit this code, and then check the candidateObject, it's candidateid value is incorrect. In the DB candidateid is the identity column and primary key. In this case it is 2572884 in the DB but when I look in the candidateObject is says the value returned is something like 0x00274254. Anyone know what might cause something like this?
I think your query is returning the correct record, since 0x00274254 (base 16) = 2572884 (base 10).
If you are checking the value using the debugger, make sure you have the Hexadecimal Display option turned off (see here for more info: Visual Studio debugger - Displaying integer values in Hex).

Dynamics GP Web Service -- Returning list of sales order based on specific criteria

For a web application, I need to get a list or collection of all SalesOrders that meet the folowing criteria:
Have a WarehouseKey.ID equal to "test", "lucmo" or "Inno"
Have Lines that have a QuantityToBackorder greater than 0
Have Lines that have a RequestedShipDate greater than current day.
I've succesfully used these two methods to retrieve documents, but I can't figure out how return only the ones that meet above criteria.
http://msdn.microsoft.com/en-us/library/cc508527.aspx
http://msdn.microsoft.com/en-us/library/cc508537.aspx
Please help!
Short answer: your query isn't possible through the GP Web Services. Even your warehouse key isn't an accepted criteria for GetSalesOrderList. To do what you want, you'll need to drop to eConnect or direct table access. eConnect has come a long way in .Net if you use the Microsoft.Dynamics.GP.eConnect and Microsoft.Dynamics.GP.eConnect.Serialization libraries (which I highly recommend). Even in eConnect, you're stuck with querying based on the document header rather than line item values, though, so direct table access may be the only way you're going to make it work.
In eConnect, the key piece you'll need is generating a valid RQeConnectOutType. Note the "ForList = 1" part. That's important. Since I've done something similar, here's what it might start out as (you'd need to experiment with the capabilities of the WhereClause, I've never done more than a straightforward equal):
private RQeConnectOutType getRequest(string warehouseId)
{
eConnectOut outDoc = new eConnectOut()
{
DOCTYPE = "Sales_Transaction",
OUTPUTTYPE = 1,
FORLIST = 1,
INDEX1FROM = "A001",
INDEX1TO = "Z001",
WhereClause = string.Format("WarehouseId = '{0}'", warehouseId)
};
RQeConnectOutType outType = new RQeConnectOutType()
{
eConnectOut = outDoc
};
return outType;
}
If you have to drop to direct table access, I recommend going through one of the built-in views. In this case, it looks like ReqSOLineView has the fields you need (LOCNCODE for the warehouseIds, QTYBAOR for backordered quantity, and ReqShipDate for requested ship date). Pull the SOPNUMBE and use them in a call to GetSalesOrderByKey.
And yes, hybrid solutions kinda suck rocks, but I've found you really have to adapt if you're going to use GP Web Services for anything with any complexity to it. Personally, I isolate my libraries by access type and then use libraries specific to whatever process I'm using to coordinate them. So I have Integration.GPWebServices, Integration.eConnect, and Integration.Data libraries that I use practically everywhere and then my individual process libraries coordinate on top of those.

Resources