MS CRM: Paging cookie bug? - sql-server

According to this article there is a serious bug in how the paging cookie is managed in Microsoft CRM. In short, the bug appears when trying to retrieve more than 5000 records in a one-to-many relationship. The author states that that since the parent entity does not contain a unique guid, the paging cookie will also not be unqiue, which might lead to that there are plenty of records that will go missing when retriving the next page of records.
Has anyone experienced this bug? How did you get around it?
One way is of course to turn the query around to use the child entity as the primary entity. In this way will every record will be unique. But this is not an optimal solution either since I have to manually change it back in code.
Another way that I have noticed is that when i´m specifying the order on the child entity like this: linkedEntity.Orders.Add(OrderType.Ascending), then the paging cookie will always be empty. This removes the problem that records go missing, but as I understand, this leads to a lot of overhead in SQL.
The best way would of course be if there is any way to make the paging cookie contain both the parent and child record. But I have not found any way yet to do that. Any idea?

I have experienced this.
I worked around it by simply not using the paging cookie, you can still page correctly without it.
For example:
int fetchCount = 3;
int pageNumber = 1;
int recordCount = 0;
QueryExpression pagequery = new QueryExpression("account");
while (true)
{
EntityCollection results = _serviceProxy.RetrieveMultiple(pagequery);
if (results.Entities != null)
{
foreach (Account acct in results.Entities)
{
Console.WriteLine(acct.Id);
}
}
if (results.MoreRecords)
{
pagequery.PageInfo.PageNumber++;
//pagequery.PageInfo.PagingCookie = results.PagingCookie; <-- Don't add the paging cookie here
}
else
{
break;
}
}

Related

How to filter multiple line of text field using Sharepoint Rest API?

Hi I'm having trouble in filtering SharePoint documents through the use of Rest API since I'm using multiple lines of texts(Plain text) column to filter them out. It only returns null result after trying it out.
Single line of text column seems to work well but I need Multiple lines of text because the metadata exceeds the 255 char limit.
I'm new to SharePoint, please help. Thank you
I am using the API to pull from a multiple line column, Product.
The first part is just to keep looking if empty and I keep js old school for IE 11 users. Product is defined earlier in the js as a variable based on the page, I am using this in many ways. Basically the answer to your question is check for null and instruct to continue, then else if and use indexOf().
for (i = 0; i < data.d.results.length; i++) {
if (data.d.results[i].Product == null) {
continue;
} else if (data.d.results[i].Product.indexOf(product) !== -1) {
var xid = data.d.results[i];
insertText(xid);
}
}
The success function for the GET carries over the xid, insertText(xid). Hopefully this makes sense.
go to site settings > site permissions > anonymous access... you gotta disable the check against Client Object Model permission Requirement

Document status that depend on the user type object

I have the following objects: L1User, L2User, L3User (all inherits from User) and Document.
Every user can create the document but depending on the user type, the document will have a different status. So in case it's L1User, the document will be created with L1 status and so on:
Solution 1
Please note that after document is created, it will be saved in the database, so it should be natural to have a method create_document(User user) in Document object. In the method body I could check which type is the user and set manually appropriate status. Such approach seems rather not OOP to me.
Solution 2
Ok, so the next approach would be to have all users implement a common method (say create_document(Document doc)) which will set a status associated with the user and save the document in the database. My doubt here is that the document should be saved in it's own class, not the user.
Solution 3
So the final approach would similar to the above, except that the user will return modified document object to it's create_document(User user) method and save will be performed there. The definition of the method would be like this:
create_document(User user)
{
this = user.create_document(this);
this->save();
}
It also doesn't seems right to me...
Can anyone suggest a better approach?
I think that both Solutions 2 and 3 are ok from the OO point of view, since you are properly delegating the status assignment to the user object (contrary to solution 1, whare you are basically doing a switch based on the user type). Whether to choose 2 or 3 is more a matter of personal tastes.
However, I have a doubt: why do you pass a document to a create_document() method? I would go for a message name that best describes what it does. For example, in solution 3 (the one I like the most) I would go for:
Document>>create_document(User user)
{
this = user.create_document();
this->save();
}
and then
L1User>>create_document()
{
return new Document('L1');
}
or
Document>>create_document(User user)
{
this = new Document()
this = user.set_document_type(this);
this->save();
}
and then
L1User>>set_document_type(document)
{
document.setType('L1');
}
Edit: I kept thinking about this and there is actually a fourth solution. However the following approach works only if the status of a document doesn't change through its lifetime and you can map the DB field with a getter instead of a property. Since the document already knows the user and the status depends on the user, you can just delegate:
Document>>getStatus()
{
return this.user.getDocumentStatus();
}
HTH

Retrieving Specific Active Directory Record Attributes using C#

I've been asked to set up a process which monitors the active directory, specifically certain accounts, to check that they are not locked so that should this happen, the support team can get an early warning.
I've found some code to get me started which basically sets up requests and adds them to a notification queue. This event is then assigned to a change event and has an ObjectChangedEventArgs object passed to it.
Currently, it iterates through the attributes and writes them to a text file, as so:
private static void NotifierObjectChanged(object sender,
ObjectChangedEventArgs e)
{
if (e.ResultEntry.Attributes.AttributeNames == null)
{
return;
}
// write the data for the user to a text file...
using (var file = new StreamWriter(#"C:\Temp\UserDataLog.txt", true))
{
file.WriteLine("{0} {1}", DateTime.UtcNow.ToShortDateString(), DateTime.UtcNow.ToShortTimeString());
foreach (string attrib in e.ResultEntry.Attributes.AttributeNames)
{
foreach (object item in e.ResultEntry.Attributes[attrib].GetValues(typeof(string)))
{
file.WriteLine("{0}: {1}", attrib, item);
}
}
}
}
What I'd like is to check the object and if a specific field, such as name, is a specific value, then check to see if the IsAccountLocked attribute is True, otherwise skip the record and wait until the next notification comes in. I'm struggling how to access specific attributes of the ResultEntry without having to iterate through them all.
I hope this makes sense - please ask if I can provide any additional information.
Thanks
Martin
This could get gnarly depending upon your exact business requirements. If you want to talk in more detail ping me offline and I'm happy to help over email/phone/IM.
So the first thing I'd note is that depending upon what the query looks like before this, this could be quite expensive or error prone (ie missing results). This worries me somewhat as most sample code out there gets this wrong. :) How are you getting things that have changed? While this sounds simple, this is actually a somewhat tricky question in directory land, given the semantics supported by AD and the fact that it is a multi-master system where writes happen all over the place (and replicate in after the fact).
Other variables would be things like how often you're going to run this, how large the data set could be in AD, and so on.
AD has some APIs built to help you here (the big one that comes to mind is called DirSync) but this can be somewhat complicated if you haven't used it before. This is where the "ping me offline" part comes in.
To your exact question, I'm assuming your result is actually a SearchResultEntry (if not I can revise, tell me what you have in hand). If that is the case then you'll find an Attributes field hanging off of that guy, and from there there is AttributeNames and Values. I think you'll see how it works from there if you have Values in hand, for example:
foreach (var attr in sre.Attributes.Values)
{
var da = (DirectoryAttribute)attr;
Console.WriteLine(da.Name);
foreach (var val in da.GetValues(typeof(byte[])))
{
// Handle a byte[] val ...
}
}
As I said, if you have something other than a SearchResultEntry in hand, let us know and I can revise the code sample.

On Google App Engine (GAE), how do I search on the Key/ID field?

I've got this code (Java, GAE):
// Much earlier:
playerKey = KeyFactory.keyToString(somePlayer.key);
// Then, later...
PersistenceManager pm = assassin.PMF.get().getPersistenceManager();
Key targetKey = KeyFactory.stringToKey(playerKey);
Query query = pm.newQuery(Player.class);
query.setFilter("__key__ == keyParam");
query.declareParameters("com.google.appengine.api.datastore.Key keyParam");
List<Player> players = (List<Player>) query.execute(targetKey); // <-- line 200
which generates this error:
javax.jdo.JDOFatalUserException: Unexpected expression type while parsing query. Are you certain that a field named __key__ exists on your object?
at org.datanucleus.jdo.NucleusJDOHelper.getJDOExceptionForNucleusException(NucleusJDOHelper.java:354)
at org.datanucleus.jdo.JDOQuery.execute(JDOQuery.java:252)
at myapp.Player.validPlayerWithKey(Player.java:200)
// [etc., snip]
But I'm not sure what it wants. I'm trying to search on the JDO id field, which I I thought I read had the special name __key__, in the documentation.
I've tried it with both
query.setFilter("__key__ == keyParam");
and
query.setFilter("ID == keyParam");
with the same results. So, what am I doing wrong? Or, more importantly, how do I do it correctly?
Thanks!
Edit: For completeness's sake, here is the final, working code (based on Gordon's answer, which I have accepted as correct):
Player result = null;
if (playerKey == null)
{
log.log(Level.WARNING, "Tried to find player with null key.");
}
else
{
PersistenceManager pm = assassin.PMF.get().getPersistenceManager();
try {
result = (Player) pm.getObjectById(Player.class, playerKey);
} catch (javax.jdo.JDOObjectNotFoundException notFound) {
// Player not found; we will return null.
result = null;
}
pm.close();
}
return result;
If your objective is to get an object by key, then you should use the PersistenceManager's getObjectByID() method. More details here.
As an aside, trying to construct a query to get something by it's key is something you shouldn't need to do. Although this is how you would work with an SQL database, the Google Data Store does things differently, and this is one of those cases where rather than go through the trouble of constructing a query, Google App Engine lets you get what you want directly. After all, you should only have one entity in the database with a particular key, so there's nothing in the rest of the machinery of a GQL query that you need in this case, hence it can all be skipped for efficiency.
I would recommend you to use the JPA ( http://code.google.com/appengine/docs/java/datastore/usingjpa.html ) to access your data in GAE, it has the very important advantage that you can use the widely known and documented JPA standard (and its JPAQL querying language) to do this kind of things, in portable way (if you stick to the JPA standard, your code will work for GAE, for Hibernate or with EclipseLink without modification)

Cannot retrieve user object from foreign key relationships using Linq to Entities statement

I'm trying to retrieve a user object from a foreign key reference but each time I try to do so nothing gets returned...
My table is set up like this:
FBUserID long,
UserID uniqueidentifier
so I have my repository try to get the User when it's provided the FBUserID:
public User getUserByFBuid(long uid)
{
User fbUser = null;
IEnumerable<FBuid> fbUids = _myEntitiesDB.FBuidSet.Where(user => user.FBUserID == uid);
fbUser = fbUids.FirstOrDefault().aspnet_Users;
return fbUser;
}
I've checked that the uid (FBUserID) passed in is correct, I've check that the UserID is matched up to the FBUserID. And I've also checked to make sure that fbUids.Count() > 0...
I've returned fbUids.FirstOrDefault().FBUserID and gotten the correct FBUserID, but any time I try to return the aspnet_Users or aspnet_Users.UserName, etc... I don't get anything returned. (I'm guessing it's getting an error for some reason)
I don't have debugging set up properly so that's probably why i'm having so much troubles... but so far all the checking I've done I've been doing return this.Json(/* stuff returned form the repository */) so that I can do an alert when it gets back to the javascript.
Anyone know why I would have troubles retrieving the user object from a foreign key relationship like that?
Or do you have any suggestions as to finding out what's wrong?
For now, with Entity Framework 1, you don't get automatic delayed loading, e.g. if you want to traverse from one entity to the next, you need to either do an .Include("OtherEntity") on your select to include those entities in the query, or you need to explicitly call .Load("OtherEntity") on your EntityContext to load that entity.
This was a design decision by the EF team not to support automagic deferred loading, since they considered it to be too dangerous; they wanted to make it clear and obvious to the user that he is also including / loading a second set of entities.
Due to high popular demand, the upcoming EF v4 (to be released with .NET 4.0 sometime towards the end of 2009) will support the automatic delayed loading - if you wish to use it. You need to explicitly enable it since it's off by default:
context.ContextOptions.DeferredLoadingEnabled = true;
See some articles on that new feature:
A Look at Lazy Loading in EF4
POCO Lazy Loading
Don't know if this is what you are asking but i do a join like so;
var votes = from av in dc.ArticleVotes
join v in dc.Votes on av.voteId equals v.id
where av.articleId == articleId
select v;
Did this help or am I off base?

Resources