We are two classes :
First class is :
public class Team
{
public Team()
{
UsersMyTeam = new List<User>();
}
public int ID { set; get; }
public string NameTeam { set; get; }
public List<User> UsersMyTeam { set; get; }
public override string ToString()
{
return "Team";
}
}
Second class is :
public class User
{
public int ID { get; set; }
public string Name { get; set; }
public string IsActive { get; set; }
public int teamID { get; set; }
public override string ToString()
{
return "User";
}
}
I use of class by code :
protected void btnTest2_Click(object sender, EventArgs e)
{
Team myTeam = new Team();
for (int i = 0; i < 4; i++)
{
User myUser = new User();
myUser.Name = i.ToString();
myTeam.UsersMyTeam.Add(myUser);
}
myTeam.NameTeam = "asdsa";
DALTableIO DTO = new DALTableIO();
DTO.Save(myTeam);
}
I have a class named DALTableIO that save class Entrance in database :
public class DALTableIO
{
public int Add(object MyClass)
{
bool IsHaveSubClass = false;
SqlParameter[] parametrs;
List<SqlParameter> listParametrs = new List<SqlParameter>();
Type t=MyClass.GetType();
PropertyInfo[] proppertis = t.GetProperties();
foreach (PropertyInfo property in proppertis)
{
if (property.Name == "ID")
continue;
if (property.PropertyType.Name.ToLower() == "list`1")
{
IsHaveSubClass = true;
continue;
}
listParametrs.Add( new SqlParameter(property.Name, property.GetValue(MyClass, null)));
}
parametrs = new SqlParameter[listParametrs.Count];
for (int i = 0; i < listParametrs.Count; i++)
{
parametrs[i] = listParametrs[i];
}
ExecuteNonQuery(CommandType.StoredProcedure,string.Concat("Add",MyClass.ToString()),parametrs);
if (IsHaveSubClass)
{
List<object> _listTeam = GetByOption(MyClass);
Type _T1=_listTeam[0].GetType();
int _IDTeam = int.Parse(_T1.GetProperty("ID").GetValue(_listTeam[0], null).ToString());
foreach (PropertyInfo property in proppertis)
{
if (property.PropertyType.Name.ToLower() == "list`1")
{
//*****How Can Access To Users to save ****
//users are List<object>
//How do I access users.
//How do I get access to any users
}
}
}
return 1;
}
tel me how can i save user.i want send each user to Add() for save.
thanks.
Replace
if (property.PropertyType.Name.ToLower() == "list`1")
{
//*****How Can Access To Users to save ****
//users are List<object>
//How do I access users.
//How do I get access to any users
}
with
if (property.PropertyType.Name.ToLower() == "list`1")
{
IList users = property.GetValue(MyClass, null) as IList;
// users is the required list of users of Team, now loop for each user to get their Id and save to database.
foreach (var user in users)
{
//do work with user here ...
}
}
Related
I'm trying to get a value session and add it into a table
here is my code i tried to get value :
public ActionResult CheckOut(FormCollection form)
{
try
{
Cart cart = Session["Cart"] as Cart;
OrderPro _order = new OrderPro();//Bảng hóa đơn sản phẩm
_order.DateOrder = DateTime.Now;
_order.AddressDeliverry = form["AddressDelivery"];
_order.IDCus = Convert.ToInt32(Session["ID"]);
db.OrderProes.Add(_order);
foreach (var item in cart.Items)
{
OrderDetail _order_detail = new OrderDetail();
_order_detail.IDOrder = _order.ID;
_order_detail.IDProduct = item.product.ProductID;
_order_detail.UnitPrice = (double)item.product.Price;
_order_detail.Quantity = item.quantity;
db.OrderDetails.Add(_order_detail);
}
db.SaveChanges();
cart.ClearCart();
return RedirectToAction("CheckOut_Success", "GioHang");
}
catch
{
return Content("<script language='javascript' type='text/javascript'>alert('Đã xảy ra lỗi, vui lòng kiểm tra thông tin');</script>");
}
}
here is the code Session :
public ActionResult Login(CustomerUser cus)
{
var check = db.CustomerUsers.Where(s => s.NameUser == cus.NameUser && s.PasswordUser == cus.PasswordUser).FirstOrDefault();
if(check == null)
{
ViewBag.ErrorLogin = "Sai info đăng nhập";
return View("Index");
}
else
{
db.Configuration.ValidateOnSaveEnabled = false;
Session["NameUser"] = cus.NameUser;
Session["PasswordUser"] = cus.PasswordUser;
Session["ID"] = cus.ID;
return RedirectToAction("DichVu", "Product");
}
}
Here is the model Session ID :
public partial class CustomerUser
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public CustomerUser()
{
this.OrderProes = new HashSet<OrderPro>();
}
public int ID { get; set; }
public string NameUser { get; set; }
public string PasswordUser { get; set; }
public string PhoneUser { get; set; }
public string EmailUser { get; set; }
}
i tried to debug but i get a error like this
enter image description here
hello community I am implementing a system to audit the modifications that are made in my application carry out the process that is described in this article:
https://codewithmukesh.com/blog/audit-trail-implementation-in-aspnet-core/?unapproved=50671&moderation-hash=71700d12d4ebaf51ad9d90c4a9834324#comment-50671
but I don't know how to get the login of my application, to login I use web token and authentication provider.
any suggestion how to do it? I don't know if it can be done with serilog or something similar
this is my code:
public class Audit
{
public int Id { get; set; }
public string UserId { get; set; }
public string Type { get; set; }
public string TableName { get; set; }
public DateTime DateTime { get; set; }
public string OldValues { get; set; }
public string NewValues { get; set; }
public string AffectedColumns { get; set; }
public string PrimaryKey { get; set; }
}
public enum AuditType
{
None = 0,
Create = 1,
Update = 2,
Delete = 3
}
public class AuditEntry
{
public AuditEntry(EntityEntry entry)
{
Entry = entry;
}
public EntityEntry Entry { get; }
public string UserId { get; set; }
public string TableName { get; set; }
public Dictionary<string, object> KeyValues { get; } = new Dictionary<string, object>();
public Dictionary<string, object> OldValues { get; } = new Dictionary<string, object>();
public Dictionary<string, object> NewValues { get; } = new Dictionary<string, object>();
public AuditType AuditType { get; set; }
public List<string> ChangedColumns { get; } = new List<string>();
public Audit ToAudit()
{
var audit = new Audit();
audit.UserId = UserId;
audit.Type = AuditType.ToString();
audit.TableName = TableName;
audit.DateTime = DateTime.Now;
audit.PrimaryKey = JsonConvert.SerializeObject(KeyValues);
audit.OldValues = OldValues.Count == 0 ? null : JsonConvert.SerializeObject(OldValues);
audit.NewValues = NewValues.Count == 0 ? null : JsonConvert.SerializeObject(NewValues);
audit.AffectedColumns = ChangedColumns.Count == 0 ? null : JsonConvert.SerializeObject(ChangedColumns);
return audit;
}
}
public abstract class AuditableIdentityContext : IdentityDbContext
{
public AuditableIdentityContext(DbContextOptions options) : base(options)
{
}
public DbSet<Audit> AuditLogs { get; set; }
public virtual async Task<int> SaveChangesAsync(string userId = null)
{
OnBeforeSaveChanges(userId);
var result = await base.SaveChangesAsync();
return result;
}
private void OnBeforeSaveChanges(string userId)
{
ChangeTracker.DetectChanges();
var auditEntries = new List<AuditEntry>();
foreach (var entry in ChangeTracker.Entries())
{
if (entry.Entity is Audit || entry.State == EntityState.Detached || entry.State == EntityState.Unchanged)
continue;
var auditEntry = new AuditEntry(entry);
auditEntry.TableName = entry.Entity.GetType().Name;
auditEntry.UserId = userId;
auditEntries.Add(auditEntry);
foreach (var property in entry.Properties)
{
string propertyName = property.Metadata.Name;
if (property.Metadata.IsPrimaryKey())
{
auditEntry.KeyValues[propertyName] = property.CurrentValue;
continue;
}
switch (entry.State)
{
case EntityState.Added:
auditEntry.AuditType = Enums.AuditType.Create;
auditEntry.NewValues[propertyName] = property.CurrentValue;
break;
case EntityState.Deleted:
auditEntry.AuditType = Enums.AuditType.Delete;
auditEntry.OldValues[propertyName] = property.OriginalValue;
break;
case EntityState.Modified:
if (property.IsModified)
{
auditEntry.ChangedColumns.Add(propertyName);
auditEntry.AuditType = Enums.AuditType.Update;
auditEntry.OldValues[propertyName] = property.OriginalValue;
auditEntry.NewValues[propertyName] = property.CurrentValue;
}
break;
}
}
}
foreach (var auditEntry in auditEntries)
{
AuditLogs.Add(auditEntry.ToAudit());
}
}
}
I use a custom Controller that inherits from the built-in Controller, and added a CurrentUserName property. The problem is that Controller.User is not yet initialized in the Controller constructor. I override Controller.OnActionExecuting(), where the User exists, and use that to set my custom property.
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var authenticatedUser = User;
if (authenticatedUser != null)
{
string userId = authenticatedUser.FindFirstValue(ClaimTypes.NameIdentifier);
if (userId != null)
{
_currentUserId = int.Parse(userId, CultureInfo.InvariantCulture);
string userName = authenticatedUser.FindFirstValue(ClaimTypes.Name);
_context.CurrentUserName = userName;
_userIsAdmin = authenticatedUser.IsInRole(ConferenceRoleTypes.WebAdmin);
}
}
base.OnActionExecuting(filterContext);
}
Hello I have a 'RestrictAccessController' That looks like this
public class RestrictAccessController : Controller
{
private PIC_Program_1_0Context db = new PIC_Program_1_0Context();
public ActionResult Index()
{
return View ();
}
}
[AttributeUsage(AttributeTargets.Method, AllowMultiple=true)]
public class RestrictAccessAttribute : ActionFilterAttribute
{
private PIC_Program_1_0Context db = new PIC_Program_1_0Context();
public AccessRestrictions restriction { get; set; }
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
base.OnActionExecuting(filterContext);
// here's where we check that the current action is allowed by the current user
if (!IGT.canAccess(IGT.userId, restriction, false))
{
string url = IGT.baseUrl+"/Home/NotAllowed";
string msg = "This page requires " + IGT.DisplayEnum(restriction) + " access";
filterContext.Result = new RedirectResult("~/Home/NotAllowed?msg="+HttpUtility.HtmlEncode(msg));
}
}
And a Config model that looks like this
public enum AccessRestrictions
{
[Display(Name = "Disposal Orders")]
ModifyDisposalOrder,
[Display(Name = "Admin")]
Admin
}
public class userAccess
{
[Key]
public int ID { get; set; }
public AccessRestrictions restriction { get; set; }
public bool allow { get; set; }
public int userID { get; set; }
}
public class configDetails
{
public int ID {get; set;}
public string Name {get; set;}
public string Value {get;set;}
public bool deleted {get;set;}
public DateTime updateTime { get; set; }
}
public class Config
{
public int ID { get; set; }
[Display(Name = "Configuration Date")]
public DateTime TargetDate { get; set; }
[Display(Name = "Enable Access Restrictions")]
public bool restrictAccess { get; set; }
}
What I want to do is edit what my 'ChangeStatus' dropdown looks like based on whether they have the Admin access restriction or not. Here is the controller method that I want to edit
[RestrictAccess(restriction = AccessRestrictions.ModifyDisposalOrder)]
public ActionResult ChangeStatus(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
DisposalOrder disposalOrder = db.disposalOrders.Find(id);
if (disposalOrder == null)
{
return HttpNotFound();
}
switch (disposalOrder.Status)
{
case DOStatus.Pending:
ViewBag.statusList = new List<Object>
{
new {value = DOStatus.Pending, text = "Pending"},
new {value = DOStatus.Disposed, text = "Disposed" }
};
break;
case DOStatus.Disposed:
// if(restriction = AccessRestrictions.ModifyDisposalOrder)
ViewBag.statusList = new List<Object>
{
new {value = DOStatus.Pending, text = "Pending"},
new {value = DOStatus.Disposed, text = "Disposed" }
};
//else
//{
// new { value = DOStatus.Disposed, text = "Disposed" }
// };
break;
};
return View(disposalOrder);
}
Here is my Startup file
public class LdapAuthentication
{
private string _adUser = ConfigurationManager.AppSettings["ADUserName"];
private string _adPW = ConfigurationManager.AppSettings["ADPassword"];
private string _domain = ConfigurationManager.AppSettings["ADDomain"];
public LdapAuthentication() {
}
public string authenticate(string username, string pwd)
{
using (var context = new PrincipalContext(ContextType.Domain, _domain, _adUser, _adPW)) {
//Username and password for authentication.
if (context.ValidateCredentials(username, pwd)) {
UserPrincipal user = UserPrincipal.FindByIdentity(context, username);
Internal internalUser = new Internal {
UserName = user.SamAccountName,
ContactName = user.DisplayName,
Email = user.UserPrincipalName
};
//Search if the user account already exists in the database
PIC_Program_1_0Context db = new PIC_Program_1_0Context();
Internal existing = db.Internals.Where(x => x.UserName == user.SamAccountName).FirstOrDefault();
// If it does not, create a new user account
if (existing == null) {
// add a new Internal entry for this user
existing = new Internal {
UserName = user.SamAccountName,
ContactName = user.DisplayName,
Email = user.UserPrincipalName
};
db.Internals.Add(existing);
db.SaveChanges();
// If it does exist, but some of the data does not match, update the data
} else if(existing != internalUser) {
existing.ContactName = internalUser.ContactName;
existing.Email = internalUser.Email;
db.SaveChanges();
}
return user.SamAccountName;
} else {
return null;
}
}
}
public UserPrincipal getUserPrincipal(string username)
{
using (var context = new PrincipalContext(ContextType.Domain, _domain, _adUser, _adPW))
{
return UserPrincipal.FindByIdentity(context, username);
}
}
Is it possible for me to accomplish this?
Ok, I think I understand your question now. You need to access the User's claims. MVC Controllers have this, half way, built in.
if (User.HasClaim("ClaimNameHere", "Admin"))
{
}
Solved by adding
if (IGT.canAccess(IGT.userId, AccessRestrictions.Admin, false))
I am working with some code that uses Columns.Add in conjunction with a lambda expression and would like to understand why/how it works. Here is a code snippet:
public ReportGrid(List<ReportRowDataContract> items)
: base(items)
{
if (items[0].ReportData1 != null)
{
if (items[0].ReportData1.DecimalValue != null)
{
Columns.Add(m => m.ReportData1.DecimalValue).Titled(items[0].ReportData1.Name).Encoded(false).
Sanitized(false).RenderValueAs(
m => (string.IsNullOrEmpty(#m.ReportData1.DisplayFormat)) ? Convert.ToDecimal(#m.ReportData1.DecimalValue).ToString("N") : Convert.ToDecimal(#m.ReportData1.DecimalValue).ToString(#m.ReportData1.DisplayFormat));
if (items[0].ReportData1.SumValue || items[0].ReportData1.AvgValue)
{
displaySummary = true;
SummaryData.Add(
new ReportDataDataContract
{
Name = items[0].ReportData1.Name,
AvgValue = items[0].ReportData1.AvgValue,
DecimalValue = 0
});
}
}
else if (items[0].ReportData1.IntValue != null)
{
Columns.Add(m => m.ReportData1.IntValue).Titled(items[0].ReportData1.Name);
if (items[0].ReportData1.SumValue || items[0].ReportData1.AvgValue)
{
displaySummary = true;
SummaryData.Add(
new ReportDataDataContract
{
Name = items[0].ReportData1.Name,
AvgValue = items[0].ReportData1.AvgValue,
IntValue = 0
});
}
}
else
{
Columns.Add(m => m.ReportData1.StringValue).Titled(items[0].ReportData1.Name);
}
}
if (items[0].ReportData2 != null)
{
if (items[0].ReportData2.DecimalValue != null)
{
Columns.Add(m => m.ReportData2.DecimalValue).Titled(items[0].ReportData2.Name).Encoded(false).
Sanitized(false).RenderValueAs(
m => (string.IsNullOrEmpty(#m.ReportData2.DisplayFormat)) ? Convert.ToDecimal(#m.ReportData2.DecimalValue).ToString("N") : Convert.ToDecimal(#m.ReportData2.DecimalValue).ToString(#m.ReportData1.DisplayFormat));
if (items[0].ReportData2.SumValue || items[0].ReportData2.AvgValue)
{
displaySummary = true;
SummaryData.Add(
new ReportDataDataContract
{
Name = items[0].ReportData2.Name,
AvgValue = items[0].ReportData2.AvgValue,
DecimalValue = 0
});
}
}
else if (items[0].ReportData2.IntValue != null)
{
Columns.Add(m => m.ReportData2.IntValue).Titled(items[0].ReportData2.Name);
if (items[0].ReportData2.SumValue || items[0].ReportData2.AvgValue)
{
displaySummary = true;
SummaryData.Add(
new ReportDataDataContract
{
Name = items[0].ReportData2.Name,
AvgValue = items[0].ReportData2.AvgValue,
IntValue = 0
});
}
}
else
{
Columns.Add(m => m.ReportData2.StringValue).Titled(items[0].ReportData2.Name);
}
}
This method consists of code that repeats itself out to ReportData6, changing only the ReportData field name with each repetition.
Here is the ReportRowDataContract class:
public class ReportRowDataContract
{
public ReportDataDataContract ReportData1 { get; set; }
public ReportDataDataContract ReportData2 { get; set; }
public ReportDataDataContract ReportData3 { get; set; }
public ReportDataDataContract ReportData4 { get; set; }
public ReportDataDataContract ReportData5 { get; set; }
public ReportDataDataContract ReportData6 { get; set; }
// an indexed property - for accessing report data fields by index
public ReportDataDataContract this[int i]
{
get
{
return new ReportDataDataContract[]
{
ReportData1,
ReportData2,
ReportData3,
ReportData4,
ReportData5,
ReportData6
}[i];
}
}
public int GetReportDataFieldCount()
{
return 6;
}
}
Unfortunately, I cannot change the structure of this class so I'm trying to convert the first code block into a method that loops. However, I'm stuck on what the Columns.Add is actually adding to.
Here is my code thus far:
public ReportGrid(List<ReportRowDataContract> items)
: base(items)
{
// get count of how many fields exist in ReportRowDataContract
int reportDataFieldCount = (new ReportRowDataContract()).GetReportDataFieldCount();
// create columns for grid for each field in ReportRowDataContract
//foreach (ReportRowDataContract item in items)
//{
int i = 0;
while (i < reportDataFieldCount)
{
AddGridColumn(items[0][i]);
i++;
}
//}
}
private void AddGridColumn(ReportDataDataContract reportColumn)
{
if (reportColumn != null)
{
if (reportColumn.DecimalValue != null)
{
Columns.Add(m => m.ReportData1.DecimalValue).Titled(reportColumn.Name).Encoded(false).
Sanitized(false).RenderValueAs(
m => (string.IsNullOrEmpty(#m.ReportData1.DisplayFormat)) ?
Convert.ToDecimal(#m.ReportData1.DecimalValue).ToString("N") :
Convert.ToDecimal(#m.ReportData1.DecimalValue).ToString(#m.ReportData1.DisplayFormat));
if (reportColumn.SumValue || reportColumn.AvgValue)
{
displaySummary = true;
SummaryData.Add(
new ReportDataDataContract
{
Name = reportColumn.Name,
AvgValue = reportColumn.AvgValue,
DecimalValue = 0
});
}
}
else if (reportColumn.IntValue != null)
{
Columns.Add(m => m.ReportData1.IntValue).Titled(reportColumn.Name);
if (reportColumn.SumValue || reportColumn.AvgValue)
{
displaySummary = true;
SummaryData.Add(
new ReportDataDataContract
{
Name = reportColumn.Name,
AvgValue = reportColumn.AvgValue,
IntValue = 0
});
}
}
else
{
Columns.Add(m => m.ReportData1.StringValue).Titled(reportColumn.Name);
}
}
}
In the AddGridColumn method the part that is problematic is m => m.ReportData1. It's not dynamic so the first loop through is fine but on the second loop through an exception is thrown: System.ArgumentException {"Column 'ReportData1.StringValue' already exist in the grid"}. I know the m.ReportData1 needs to be changed or the approach modified...just don't know how to go about it.
Edit #1: Disabled the foreach per VitezslavSimon's insight. The same exception message is being thrown.
Edit #2: Base class of grid (I think).
public class Grid<T> : GridBase<T>, IGrid where T : class
{
public Grid(IEnumerable<T> items);
public Grid(IQueryable<T> items);
public IGridColumnCollection<T> Columns { get; }
public bool DefaultFilteringEnabled { get; set; }
public bool DefaultSortEnabled { get; set; }
public virtual int DisplayingItemsCount { get; }
public bool EnablePaging { get; set; }
public string Language { get; set; }
public IGridPager Pager { get; set; }
public GridRenderOptions RenderOptions { get; set; }
public ISanitizer Sanitizer { get; set; }
public override IGridSettingsProvider Settings { get; set; }
public virtual void AutoGenerateColumns();
protected internal virtual IEnumerable<T> GetItemsToDisplay();
}
It seems you need to add columns only once there. Try to help it by declaring a flag there. It also depends how your grid component is working behind.
Your code with draft of proposed change:
public ReportGrid(List<ReportRowDataContract> items)
: base(items)
{
// get count of how many fields exist in ReportRowDataContract
int reportDataFieldCount = (new ReportRowDataContract()).GetReportDataFieldCount();
// create columns for grid for each field in ReportRowDataContract
bool flag = true;
foreach (ReportRowDataContract item in items)
{
int i = 0;
if (flag) {
while (i < reportDataFieldCount)
{
AddGridColumn(items[0][i]);
i++;
}
flag = false;
}
}
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
The title is a little prosaic, I know. I have 3 classes (Users, Cases, Offices). Users and Cases contain a list of Offices inside of them. I need to compare the Office lists from Users and Cases and if the ID's of Offices match, I need to add those IDs from Cases to the Users. So the end goal is to have the Users class have any Offices that match the Offices in the Cases class.
To add clarity, I am looking to compare the two officeLists (users.officeList and cases.OfficeList) and when any Cases.OfficeList.ID == Users.OfficeList.ID, I need to add that Case.ID to the list of Users.caseAdminIDList
Any ideas?
My code (which isnt working)
foreach (Users users in userList)
foreach (Cases cases in caseList)
foreach (Offices userOffice in users.officeList)
foreach (Offices caseOffice in cases.officeList)
{
if (userOffice.ID == caseOffice.ID)
users.caseAdminIDList.Add(cases.adminID);
}//end foreach
//start my data classes
class Users
{
public Users()
{
List<Offices> officeList = new List<Offices>();
List<int> caseAdminIDList = new List<int>();
ID = 0;
}//end constructor
public int ID { get; set; }
public string name { get; set; }
public int adminID { get; set; }
public string ADuserName { get; set; }
public bool alreadyInDB { get; set; }
public bool alreadyInAdminDB { get; set; }
public bool deleted { get; set; }
public List<int> caseAdminIDList { get; set; }
public List<Offices> officeList { get; set; }
}
class Offices
{
public int ID { get; set; }
public string name { get; set; }
}
class Cases
{
public Cases()
{
List<Offices> officeList = new List<Offices>();
ID = 0;
}//end constructor
public int ID { get; set; }
public string name { get; set; }
public int adminID { get; set; }
public bool alreadyInDB { get; set; }
public bool deleted { get; set; }
public List<Offices> officeList { get; set; }
}
//in my main method
private bool grabCasesFromAdminDB() //gets cases from DB1 (AdminDB)
{
DatabaseIO dbIO = new DatabaseIO();
caseList = dbIO.getCasesFromAdminDB(adminDBConString, caseList).ToList();
if (dbIO.errorMessage == null || dbIO.errorMessage.Equals(""))
{
if (getCaseOfficeRelationship())
return true;
else
return false;
}//end if
else
{
MessageBox.Show(dbIO.errorMessage, "Admin DB Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}//end else
}//end method
private bool grabCasesFromListDB()//grabs cases from the main db
{
DatabaseIO dbIO = new DatabaseIO();
caseList = dbIO.getCasesFromMainDB(connectionString, caseList).ToList();
if (dbIO.errorMessage == null || dbIO.errorMessage.Equals(""))
return true;
else
{
MessageBox.Show(dbIO.errorMessage, "Main DB Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}//end else
}//end method
private bool getCaseOfficeRelationship()//adds office relationship to cases
{
DatabaseIO dbIO = new DatabaseIO();
caseList = dbIO.getOfficeToCaseRelationship(connectionString, caseList).ToList();
if (dbIO.errorMessage == null || dbIO.errorMessage.Equals(""))
{
if (getOfficeNamesByID())
return true;
else
return false;
}//end if
else
{
MessageBox.Show(dbIO.errorMessage, "Cases To Offices Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}//end else
}//end method
private bool getOfficeNamesByID()//grabs the id of the offices by name
{
List<Offices> officeList = new List<Offices>();
DatabaseIO dbIO = new DatabaseIO();
officeList = dbIO.getOfficeNamesByOfficeID(connectionString).ToList();
if (dbIO.errorMessage == null || dbIO.errorMessage.Equals(""))
{
matchOfficeNamesToIDs(officeList);
return true;
}//end if
else
{
MessageBox.Show(dbIO.errorMessage, "Getting Office List Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}//end else
}//end method
private void matchOfficeNamesToIDs(List<Offices> officeList)
{
foreach (Cases cases in caseList)
if (cases.officeList != null)
foreach (Offices office in cases.officeList)
{
foreach (Offices innerOffice in officeList)
if (innerOffice.ID == office.ID)
office.name = innerOffice.name;
}//end foreach
}//end method
//an example of my DBIO class
public List<Cases> getCasesFromAdminDB(string adminDBConString, List<Cases> caseList)
{
try
{
Cases cases = null;
SqlConnection con = new SqlConnection();
con.ConnectionString = adminDBConString;
con.Open();
SqlCommand command = new SqlCommand();
command.Connection = con;
command.CommandText = "select CS_Case_ID, Case_Name from CS_Case where CS_Product_Type_ID = 2 and CS_Case_Status_ID = 1";
SqlDataReader thisReader = command.ExecuteReader();
int idxID = thisReader.GetOrdinal("CS_Case_ID");
int idxName = thisReader.GetOrdinal("Case_Name");
while (thisReader.Read())
{
bool found = false;
foreach (Cases tempCase in caseList)
{
if (tempCase.adminID == Int32.Parse(thisReader.GetValue(idxID).ToString()))
{
tempCase.alreadyInDB = true;
found = true;
}//end if
}//end foreach
if (!found)
{
cases = new Cases();
cases.adminID = Int32.Parse(thisReader.GetValue(idxID).ToString());
cases.name = thisReader.GetValue(idxName).ToString();
cases.alreadyInDB = false;
cases.officeList = new List<Offices>();
caseList.Add(cases);
}//end if
}//end while
thisReader.Close();
return caseList;
}//end try
catch (Exception excep1)
{
errorMessage = "Cases could not be loaded from the Admin Console." + "\r\n" + "Error message: " + excep1.ToString();
return caseList;
}//end catch
}//end method
Complex querying like this is best handled by LINQ. If you had a common element on both Users and Cases, then this would be a job for a join. But in this case instead of a common element, they each contain lists, and you want to "join" on those where the two lists have a common element.
So, to start off, what's the condition for a particular case to be included for a user?
case.officeList.Any(caseOffice => user.officeList.Any(userOffice => caseOffice.ID == userOffice.ID))
i.e. Any office in the case's officeList is contained in the user's officeList.
Now we have that condition, we can use it in a LINQ Where clause to pull out all the desired case:
caseList.Where(case =>
case.officeList.Any(caseOffice => user.officeList.Any(userOffice => caseOffice.ID == userOffice.ID)))
That returns our collection of cases, so finally we just want to Select out the part of the case we need, the adminID.
caseList.Where(case =>
case.officeList.Any(caseOffice => user.officeList.Any(userOffice => caseOffice.ID == userOffice.ID)))
.Select(case => case.adminID);
So putting that all together:
foreach(Users users in userList)
{
users.caseAdminIDList = caseList.Where(case =>
case.officeList.Any(caseOffice => user.officeList.Any(userOffice => caseOffice.ID == userOffice.ID)))
.Select(case => case.adminID).ToList();
}
public Cases()
{
List<Offices> officeList = new List<Offices>();
ID = 0;
}//end constructor
This is making a new varaible called officeList. It will not use the officeList outside the constructor.
This needs to be changed to:
officeList = new List<Offices>();
This will properly initialize the class field.
You can implement your Offices class like this:
class Offices:IEquatable<Offices>
{
public int ID { get; set; }
public string name { get; set; }
public bool Equals(Offices other)
{
return this.ID.Equals(other.ID);
}
public override int GetHashCode()
{
return this.ID.GetHashCode();
}
}
Then in your code to have the Users class have any Offices that match the Offices in the Cases class just do this;
usersVariable.CaseAdminIDList = usersVariable.OfficeList.Intersect(casesVariable.OfficeList).Select(o => o.ID).ToList();
Also in your users and cases class you need to initialize the list properly(you are using automatic properties and in ctor declaring and initializing a whole new variable),something
like this for example:
class Users
{
public Users()
{
officeList = new List<Offices>();
caseAdminIDList = new List<int>();
ID = 0;
}//end constructor
private List<Offices> officeList;
public List<Offices> OfficeList
{
get { return officeList; }
set { officeList = value; }
}
private List<int> caseAdminIDList;
public List<int> CaseAdminIDList
{
get { return caseAdminIDList; }
set { caseAdminIDList = value; }
}
//other members.....
}