I am trying to retrieve a random number of users from the UserProfileManager.
But I am encountering errors when deploying to the live servers. I can't seem to see what is causing the error. My code is below:
for (int i = 0; i < NumberOfUserLimit; i++)
{
UserProfile up = profileManager.GetUserProfile(random.Next(1, NumberOfUserLimit));
if (up["FirstName"] != null && up["FirstName"].Value != null && !String.IsNullOrEmpty(up["FirstName"].Value.ToString()))
{
DataRow drUserProfile;
drUserProfile = dtUserProfile.NewRow();
drUserProfile["DisplayName"] = up.DisplayName;
drUserProfile["FirstName"] = up["FirstName"].Value;
drUserProfile["LastName"] = up["LastName"].Value;
drUserProfile["Department"] = up["Department"].Value;
drUserProfile["Location"] = up["SPS-Location"].Value;
drUserProfile["HireDate"] = up["SPS-HireDate"].Value;
drUserProfile["ContactNumber"] = up["Office"].Value;
if (up["PictureURL"] != null && up["PictureURL"].Value != null && !String.IsNullOrEmpty(up["PictureURL"].Value.ToString()))
{
string cleanAccountName = up["AccountName"].Value.ToString().Replace(#"\", "_");
string pictureUrl = String.Format("https://my.someintranet.com/User Photos/Profile Pictures/{0}_MThumb.jpg", cleanAccountName);
drUserProfile["Image"] = pictureUrl;
}
else
{
drUserProfile["Image"] = "~/_layouts/images/O14_person_placeHolder_96.png";
}
drUserProfile["MySiteUrl"] = up.PublicUrl;
dtUserProfile.Rows.Add(drUserProfile);
}
}
My code works when I apply a simple foreach to my code above instead of the "for loop":
foreach (UserProfile up in profileManager)
Which proves I can return userprofiles.
Any help is appreciated.
profileManager.GetUserProfile(long recordId)
expects a recordId from userprofile table. It is not an index, so you cannot use "random".
If you want to check RecordId, you can take a look at SQL tables of ProfileDB. Table "UserProfile_Full" has MasterRecordId column. Your parameter in GetUserProfile has to match of the user profile's MasterRecordId.
you can use the following code to get your random profiles:
IEnumerator profiles = profileManager.GetEnumerator();
int index = new Random().Next(1, 100);
while (index >= 0 && profiles.MoveNext())
index--;
UserProfile currentProfile = (UserProfile)profiles.Current
Code that handles Random better
public class TestClass
{
private random = new Random();
private long totalNumberOfProfiles; //ProfileManager.Count not always returns count correctly
public TestClass()
{
//this does not have to be in constructor but point is to have it cached (reasonably)
IEnumerator profiles = profileManager.GetEnumerator();
long counter = 0;
while (profiles.MoveNext())
counter++;
this.totalNumberOfProfiles = counter;
}
public fillInDataSet()
{
//something is here...
IEnumerator profiles = profileManager.GetEnumerator();
int index = random.Next(1, totalNumberOfProfiles);
while (index >= 0 && profiles.MoveNext())
index--;
UserProfile currentProfile = (UserProfile)profiles.Current
//something is here...
}
}
Related
I want to generate a list of 300 items from a String however when this task is divided into 3 isolates,where each isolate is generating a list of 100 items it takes just as long as it would take a single isolate to generate a list of 300 items.
the fetchCoinList() method below is what is being run in the isolate and the generateList() method spawns 3 isolates.
All these isolates do work in parallel and do return their respective lists.
List<CoinData> fetchCoinList(ListConfig listConfig) {
List<CoinData> coinList = [];
for (int index = listConfig.listStart; index < listConfig.listEnd; index++) {
if (jsonDecode(listConfig.listData)['data'][index]['rank'] == null ||
jsonDecode(listConfig.listData)['data'][index]['priceUsd'] == null ||
jsonDecode(listConfig.listData)['data'][index]['changePercent24Hr'] ==
null) continue;
int rank =
int.parse(jsonDecode(listConfig.listData)['data'][index]['rank']);
String name = jsonDecode(listConfig.listData)['data'][index]['name'];
String symbol = jsonDecode(listConfig.listData)['data'][index]['symbol'];
String id = jsonDecode(listConfig.listData)['data'][index]['id'];
double value = double.parse(
jsonDecode(listConfig.listData)['data'][index]['priceUsd']);
double percentChange = double.parse(
jsonDecode(listConfig.listData)['data'][index]['changePercent24Hr']);
String image =
'https://static.coincap.io/assets/icons/${symbol.toLowerCase()}#2x.png';
print(listConfig.listEnd);
coinList.add(CoinData(rank, id, name, symbol, value, percentChange, image));
}
return coinList;
}
Future<List<CoinData>> generateList(String response) async {
print("Inside isolate");
List<CoinData> coinList = [];
List list = [];
for (int i = 0; i < 3; i++) {
ListConfig listConfig = ListConfig(response, i * 100, (i * 100) + 100);
list.add(compute(fetchCoinList, listConfig));
}
for (int i = 0; i < 3; i++) {
coinList = coinList + await list[i];
}
return coinList;
}
What could be a workaround for this problem? how would one go about generating a list of 300 or a 1000 items if required(without hanging the main thread)?
Your main issue are probably the kinda horrible way you are handling JSON parsing in fetchCoinList where you are running jsonDecode() for every field you want to extract from your JSON string.
You should instead cache the result from jsonDecode(). Also, you should also cache some of the other operations you are doing a lot.
I have made the following example of how I would rewrite the code:
List<CoinData> fetchCoinList(ListConfig listConfig) {
final jsonObject = jsonDecode(listConfig.listData) as Map<String, dynamic>;
List<CoinData> coinList = [];
for (int index = listConfig.listStart; index < listConfig.listEnd; index++) {
final dataMap = jsonObject['data'][index] as Map<String, dynamic>;
if (dataMap['rank'] == null ||
dataMap['priceUsd'] == null ||
dataMap['changePercent24Hr'] == null) continue;
print(listConfig.listEnd);
final symbol = dataMap['symbol'] as String;
coinList.add(CoinData(
rank: dataMap['rank'] as int,
name: dataMap['name'] as String,
symbol: symbol,
id: dataMap['id'] as String,
value: double.parse(jsonObject['priceUsd'] as String),
percentChange: double.parse(jsonObject['changePercent24Hr'] as String),
image:
'https://static.coincap.io/assets/icons/${symbol.toLowerCase()}#2x.png'));
}
return coinList;
}
class CoinData {
final int rank;
final String name;
final String symbol;
final String id;
final double value;
final double percentChange;
final String image;
CoinData({
required this.rank,
required this.name,
required this.symbol,
required this.id,
required this.value,
required this.percentChange,
required this.image,
});
}
I'm using the same code in 6 Areas, each a separate database. Been working fine for a long time, now fails in 3 of the 6 with a null reference exception. Classes all the same, all database tables hold data. First method is the view which displays the data, second called by a link in the view to export the data to Excel. 3 cases display and export correctly. In 2 out of the other 3 cases the data is displayed correctly in the view, and the null exception is thrown at the point the data should be being retrieved in the export method. In the last case the null exception is thrown when trying to return the view. Simply can't understand how it works in some instances but not in others.
public ActionResult PVS(string studySite, string currentFilter, int? page)
{
ViewBag.SelectedID = studySite;
if (studySite != null)
page = 1;
else
studySite = currentFilter;
ViewBag.CurrentFilter = studySite;
IQueryable<PVS> schedule = db.PVS.OrderBy(v => v.SiteNumber).ThenBy(v => v.Participant);
if (studySite != null)
{
string selectedID = studySite;
images = schedule.Where(v => v.SiteNumber == selectedID);
}
int pageSize = 10;
int pageNumber = (page ?? 1);
return View(schedule.ToPagedList(pageNumber, pageSize));
}
public void ExportPVSToExcel()
{
var grid = new System.Web.UI.WebControls.GridView();
var pvs = db.PVS.OrderBy(p => p.SiteNumber).ThenBy(p => p.Participant).ToList();
grid.DataSource = pvs;
grid.DataBind();
// create an Excel worksheet for the data export
ExcelPackage excel = new ExcelPackage();
var workSheet = excel.Workbook.Worksheets.Add("PVS");
var totalCols = grid.Rows[0].Cells.Count;
var totalRows = grid.Rows.Count;
var headerRow = grid.HeaderRow;
for (var i = 1; i <= totalCols; i++)
{
workSheet.Cells[1, i].Value = headerRow.Cells[i - 1].Text;
}
for (var j = 1; j <= totalRows; j++)
{
for (var i = 1; i <= totalCols; i++)
{
var data = pvs.ElementAt(j - 1);
workSheet.Cells[j + 1, i].Value = data.GetType().GetProperty(headerRow.Cells[i - 1].Text).GetValue(data, null);
}
}
using (var memoryStream = new MemoryStream())
{
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", "attachment; filename=PVS.xlsx");
excel.SaveAs(memoryStream);
memoryStream.WriteTo(Response.OutputStream);
Response.Flush();
Response.End();
}
}
This is a project I'm doing for my own amusement.
I started out wanting to experiment with combination and permutations. In a console application I have the following code
public static void Save(string newWord)
{
using (var db = new MyDataContext())
{
var w = new Word {word = newWord};
db.Words.InsertOnSubmit(w);
db.SubmitChanges();
}
}
static void Main(string[] args)
{
var letters = new[] { 'A', 'B', 'C', '1', '2', '3'};
for (var i = 2; i < 10; i++)
{
letters.GetPermutations(a => Save(string.Join(string.Empty, a.ToArray())), i, true);
}
}
In an extension class, I have the code to generate the combinations. I found the code for the combinations here (http://blog.noldorin.com/2010/05/combinatorics-in-csharp/) for those wanting to review that.
public static void GetCombinations<T>(this IList<T> list, Action<IList<T>> action, int? resultSize = null, bool withRepetition = false)
{
if (list == null)
throw new ArgumentNullException("list");
if (action == null)
throw new ArgumentNullException("action");
if (resultSize.HasValue && resultSize.Value <= 0)
throw new ArgumentException(errorMessageValueLessThanZero, "resultSize");
var result = new T[resultSize.HasValue ? resultSize.Value : list.Count];
var indices = new int[result.Length];
for (int i = 0; i < indices.Length; i++)
indices[i] = withRepetition ? -1 : indices.Length - i - 2;
int curIndex = 0;
while (curIndex != -1)
{
indices[curIndex]++;
if (indices[curIndex] == (curIndex == 0 ? list.Count : indices[curIndex - 1] + (withRepetition ? 1 : 0)))
{
indices[curIndex] = withRepetition ? -1 : indices.Length - curIndex - 2;
curIndex--;
}
else
{
result[curIndex] = list[indices[curIndex]];
if (curIndex < indices.Length - 1)
curIndex++;
else
action(result);
}
}
}
Then I thought it would be cool to calculate the combinations for all charaters in a list, each in its own thread. So in my for/next loop, I tried
Thread t = new Thread(letters.GetPermutations(a => Save(string.Join(string.Empty, a.ToArray())), i, true));
But apparently, the Action that is being passed in, the call to the 'Save' function, is not liked in the Thread. If someone could give me a nudge in the right direction, I'd appreciate it.
Thanks,
Andy
The Thread constructor is looking for a delegate but you're appearing to pass a value instead. Try wrapping it in an ThreadStart delegate.
ThreadStart del = () => letters.GetPermutations(a => Save(string.Join(string.Empty, a.ToArray())), i, true);
Thread t = new Thread(del);
t.Start();
public List<Health_Scheme_System.Employee> GetPenEmployeeTable()
{
Health_Scheme_System.Health_Scheme_SystemDB db = new Health_Scheme_System.Health_Scheme_SystemDB();
var x = (from c in db.Employees
where c.Pensioners.Equals (1)
select c);
return x.ToList();
}
//Selecting multiple columns from an HR view table together with the scheme name of scheme.
public List<EmployeesX> GetPensioners()
{
Health_Scheme_System.Health_Scheme_SystemDB db = new Health_Scheme_System.Health_Scheme_SystemDB();
List<Health_Scheme_System.EmployeeDirectory> listEmployeeView = GetPenEmployeeView();
List<Health_Scheme_System.Employee> listEmployeeTable = GetPenEmployeeTable();
List<Health_Scheme_System.Scheme> listSchemes = GetSchemes();
List<EmployeesX> listOfEmployees = new List<EmployeesX>();
//checking for comparision of getemployeeview to getemployee table and then to getschemes
//Then display the scheme name if they are similar.
for (int i = 0; i < listEmployeeView.Count; i++)
{
EmployeesX emp = new EmployeesX();
emp.ID_NO = listEmployeeView[i].ID_NO;
emp.FIRST_NAME = listEmployeeView[i].FIRST_NAME;
emp.LAST_NAME = listEmployeeView[i].LAST_NAME;
emp.LOCATION_CODE = listEmployeeView[i].LOCATION_CODE;
for (int j = 0; j < listEmployeeTable.Count; j++)
{
if (listEmployeeTable[j].EmployeeIDCard == listEmployeeView[i].ID_NO)
{
emp.Pensioners = listEmployeeTable[j].Pensioners;
for (int k = 0; k < listSchemes.Count; k++)
{
if (listEmployeeTable[j].SchemeID == listSchemes[k].SchemeID)
{
emp.SCHEME_NAME = listSchemes[k].Name;
emp.START_DATE = listEmployeeTable[j].StartSchemeDate;
}
}
}
}
listOfEmployees.Add(emp);
}
return listOfEmployees;
}
How can I make the same method with using .equals??
Have you tried this:
var x = (from c in db.Employees
where c.Pensioners == 1
select c)
Additional info:
If you use a method on an object in a linq query subsonic needs to know how to translate that into pur SQL code. That does not work by default and must be implemented for every known method on every supported type for every dataprovider (if differs from default implementation). So there is a bunch of work to do for subsonic.
A good starting point for knowning what's supported and what not is the TSqlFormatter class. Have a look at protected override Expression VisitMethodCall(MethodCallExpression m)
https://github.com/subsonic/SubSonic-3.0/blob/master/SubSonic.Core/Linq/Structure/TSqlFormatter.cs
There is already an implementation for Equals
else if (m.Method.Name == "Equals")
{
if (m.Method.IsStatic && m.Method.DeclaringType == typeof(object))
{
sb.Append("(");
this.Visit(m.Arguments[0]);
sb.Append(" = ");
this.Visit(m.Arguments[1]);
sb.Append(")");
return m;
}
else if (!m.Method.IsStatic && m.Arguments.Count == 1 && m.Arguments[0].Type == m.Object.Type)
{
sb.Append("(");
this.Visit(m.Object);
sb.Append(" = ");
this.Visit(m.Arguments[0]);
sb.Append(")");
return m;
}
else if (m.Method.IsStatic && m.Method.DeclaringType == typeof(string))
{
//Note: Not sure if this is best solution for fixing side issue with Issue #66
sb.Append("(");
this.Visit(m.Arguments[0]);
sb.Append(" = ");
this.Visit(m.Arguments[1]);
sb.Append(")");
return m;
}
}
I suppose Prnsioners is an integer type so you basically have to add another else if and recomplie subsonic.
This should work but I haven't tested it.
else if (!m.Method.IsStatic && m.Method.DeclaringType == typeof(int))
{
sb.Append("(");
this.Visit(m.Arguments[0]);
sb.Append(" = ");
this.Visit(m.Arguments[1]);
sb.Append(")");
return m;
}
(or you can try the == approach like in the example on the top).
I am trying to implement simple paging on my sharepoint webpart. I have a single news articles list which has some simple columns. I want to be able to have then five on a page and with some numerical paging at the bottom. I have gone through the net trying to understand splistitemcollectionposition but with no luck. If anyone can help please can you give me a simple code example or some guidanc
Many thanks
Chris
I would suggest using SPDataSource and a SPGridView, together they will implement paging and many other cool features with minimal or no code.
Use this a a guide for some of the classes/methods/properties you might need to use to get paging to work. Be aware that this code does not compile, i have just pulled together various code snippets that i have in my own list results framework, which includes paging, sorting, grouping and caching. It should be enough to get you started though.
public class PagedListResults : System.Web.UI.WebControls.WebParts.WebPart {
protected SPPagedGridView oGrid;
protected override void CreateChildControls() {
this.oGrid = new SPPagedGridView();
oGrid.AllowPaging = true;
oGrid.PageIndexChanging += new GridViewPageEventHandler(oGrid_PageIndexChanging);
oGrid.PagerTemplate = null; // Must be called after Controls.Add(oGrid)
oGrid.PagerSettings.Mode = PagerButtons.NumericFirstLast;
oGrid.PagerSettings.PageButtonCount = 3;
oGrid.PagerSettings.Position = PagerPosition.TopAndBottom;
base.CreateChildControls();
}
public override void DataBind() {
base.DataBind();
SPQuery q = new SPQuery();
q.RowLimit = (uint)info.PageSize;
if (!string.IsNullOrEmpty(info.PagingInfoData)) {
SPListItemCollectionPosition pos = new SPListItemCollectionPosition(info.PagingInfoData);
q.ListItemCollectionPosition = pos;
} else {
//1st page, dont need a position, and using a position breaks things
}
q.Query = info.Caml;
SPListItemCollection items = SPContext.Current.List.GetItems(q);
FilterInfo info = null;
string tmp = "<View></View>";
tmp = tmp.Replace("<View><Query>", string.Empty);
tmp = tmp.Replace("</Query></View>", string.Empty);
info.Caml = tmp;
info.PagingInfoData = string.Empty;
info.CurrentPage = oGrid.CurrentPageIndex;
info.PageSize = oGrid.PageSize;
if (oGrid.PageIndex == 0 || oGrid.CurrentPageIndex == 0) {
//do nothing
} else {
StringBuilder value = new StringBuilder();
value.Append("Paged=TRUE");
value.AppendFormat("&p_ID={0}", ViewState[KEY_PagingPrefix + "ID:" + oGrid.PageIndex]);
info.PagingInfoData = value.ToString();
}
int pagecount = (int)Math.Ceiling(items.Count / (double)oGrid.PageSize);
for (int i = 1; i < pagecount; i++) { //not always ascending index numbers
ResultItem item = items[(i * oGrid.PageSize) - 1];
ViewState[KEY_PagingPrefix + "ID:" + i] = item.ID;
}
oGrid.VirtualCount = items.Count;
DateTime time3 = DateTime.Now;
DataTable table = new DataTable("Data");
DataBindListData(table, items);
this.oGrid.DataSource = table;
this.oGrid.DataBind();
this.oGrid.PageIndex = oGrid.CurrentPageIndex; //need to reset this after DataBind
}
void oGrid_PageIndexChanging(object sender, GridViewPageEventArgs e) {
oGrid.PageIndex = e.NewPageIndex;
oGrid.CurrentPageIndex = oGrid.PageIndex;
}
}
public class FilterInfo {
public string Caml;
public string PagingInfoData;
public int CurrentPage;
public int PageSize;
}
public class SPPagedGridView : SPGridView {
protected override void InitializePager(GridViewRow row, int columnSpan, PagedDataSource pagedDataSource) {
pagedDataSource.AllowCustomPaging = true;
pagedDataSource.VirtualCount = virtualcount;
pagedDataSource.CurrentPageIndex = currentpageindex;
base.InitializePager(row, columnSpan, pagedDataSource);
}
private int virtualcount = 0;
public int VirtualCount {
get { return virtualcount; }
set { virtualcount = value; }
}
private int currentpageindex = 0;
public int CurrentPageIndex {
get { return currentpageindex; }
set { currentpageindex = value; }
}
}
check out my post on how to page using SPListItemCollectionPosition, I did a component to page over lists, maybe it can help -> http://hveiras.wordpress.com/2011/11/07/listpagert-using-splistitemcollectionposition/