I have a class called Employee. From my controller i am passing IEnumerable<Employee> to view. How to convert MongoDB.Driver.MongoCollection<Employee> to IEnumerable<Employee>?
public ActionResult Index()
{
var server = MongoServer.Create("mongodb://127.0.0.1");
var db = server.GetDatabase("employee");
var employeeCollection = new Collection<Employee>
{
new Employee
{
EmployeeId = new ObjectId(),
EmployeeName = "A"
},
new Employee
{
EmployeeId = new ObjectId(),
EmployeeName = "B"
}
};
var collection = db.GetCollection<Employee>("employee");
collection.InsertBatch(employeeCollection);
return View(collection);
}
You can just use FindAll and that will allow you to enumerate over the entire collection:
return View(collection.FindAll());
You could also use AsQueryable to achieve the same result:
return View(collection.AsQueryable());
But you should be careful about doing that. The collection could possibly contain millions of documents.
Related
My goal is:
I make a call to the DB which returns to me the list of all my events.
I make a second call to the db which returns to me the list of all my sub-events.
I have an EventViewModel class that contains a List <_EventsLines> class and a List <_SubEventsLines> class.
I need to send the result of these 2 query in a single view but i dont know how could i do that!
I connect to a DB Filemaker and it is based on a single view, that's why I have to make 2 calls.
But then I would like to put the results of these 2 calls in the same object (oEventViewModel) in order to send them back to my view.
Would you have a solution?
Controller
[Authorize]
[HttpGet]
public async Task<ActionResult> Index()
{
ViewBag.sessionv = HttpContext.Session.GetInt32("idMember");
FileMakerRestClient client = new FileMakerRestClient(serverName, fileName, userName, password);
var toFind = new Models.EventsLines { Zkf_CTC = 1053 };
var results = await client.FindAsync(toFind);
Models.EventViewModel oEventViewModel = new Models.EventViewModel
{
_EventsLines = (from o in results select o).ToList()
};
var xtoFind = new Models.SubEventsLines { Zkf_CTC = 1053 };
var xresults = await client.FindAsync(xtoFind);
Models.EventViewModel oSubEventViewModel = new Models.EventViewModel
{
_SubEventsLines = (from x in xresults select x).ToList()
};
ViewBag.Zkf_CTC = 1053;
ViewBag.JsonList = oEventViewModel;
return View(oEventViewModel);
}
Model
public class EventViewModel
{
public List<EventsLines> _EventsLines { get; set; }
public List<SubEventsLines> _SubEventsLines { get; set; }
}
I have IEnumerable collection like following
IEnumerable<Customer> items = new Customer[]
{
new Customer { Name = "test1", Id = 999 },
new Customer { Name = "test2", Id = 989 }
};
I want to get value using key Id
I tried like following
public int GetValue(IEnumerable<T> items,string propertyName)
{
for (int i = 0; i < items.Count(); i++)
{
(typeof(T).GetType().GetProperty(propertyName).GetValue(typeof(T), null));
// I will pass propertyName as Id and want all Id propperty values
// from items collection one by one.
}
}
If you want to retrieve a Customer name from a collection by its Id:
public string GetCustomerName(IEnumerable<Customer> customers, int id)
{
return customers.First(c => c.Id == id).Name;
}
Using LINQ you can get all customers names (values) having specific value in this way:
var valuesList = items.Where(x => x.Something == myVar).Select(v => v.Name).ToList();
For single customer name you can do this:
var singleName = items.FirstOrDefault(x => x.Id == 1)?.Name;
Obviously, the Id can be 1, 2 or any other.
Edit:
I recommend you List<Customer> instead of Customer[]
So,
var items = new List<Customer>
{
new Customer { Name = "test1", Id = 999 },
new Customer { Name = "test2", Id = 989 }
};
// I will pass propertyName as Id and want all Id propperty values
// from items collection one by one.
If I understand you correctly
public static IEnumerable<object> GetValues<T>(IEnumerable<T> items, string propertyName)
{
Type type = typeof(T);
var prop = type.GetProperty(propertyName);
foreach (var item in items)
yield return prop.GetValue(item, null);
}
Just use LINQ to achieve what you want to do. if you want to retrieve a specific value you can use where like this:
public Customer GetCustomerById(IEnumerable<Customer> items,int key)
{
return items.Where(x=>x.id==key)
.Select(x =>x.Name)
.First();
}
this will retrieve the customer who match a specific Id.
Do you want to look things up repeatedly after creating the list? If so, you might want to consider creating a dictionary to do the lookups, like so:
IEnumerable<Customer> items = new Customer[]
{
new Customer {Name = "test1", Id = 999},
new Customer {Name = "test2", Id = 989}
};
var lookup = items.ToDictionary(itemKeySelector => itemKeySelector.Id);
var result = lookup[989];
Console.WriteLine(result.Name); // Prints "test2".
I'm assuming that you don't create the collection in the first place - if you had control over creating the original collection you could use a dictionary in the first place.
private TextBox [] Collectionstextboxonpanel(Panel panel)
{
var textBoxspanel1 = panel.Controls.OfType<TextBox>(); // select controls on panle1 by type
IEnumerable<TextBox> textBoxes = textBoxspanel1; // create collection if need
TextBox[] textBoxes1 = textBoxes.ToArray(); // Array collection
return textBoxes1; // get back TextBox Collection
}
I have a Controller that I am using to pass a list of JSON data to my view. Currently I'm using Linq to Entities to populate the Viewmodel now but since it is a static list of only 15 pairs, I want to hard code the Viewmodel but I'm not sure how to do that. Here is my Controller
public JsonResult GetSites()
{
var sites = context.vAaiomsSites.Select(s => new vAaiomsSitesVM
{
ID = s.ID,
SiteName = s.SiteName
}).OrderBy(s => s.SiteName);
return Json(sites, JsonRequestBehavior.AllowGet);
}
I just need an array like this:
SiteID: 1, SiteName : Barter Island
SiteID: 2, SiteName: Cape Lisburne
....12 more times.
Use collection initializer to create an array (or List<T>) of the ViewModels:
public JsonResult GetSites()
{
var sitesArray = new vAaiomsSitesVM[]
{
new vAaiomsSitesVM
{
ID = 1,
SiteName = "Barter Island"
},
new vAaiomsSitesVM
{
ID = 2,
SiteName = "Cape Lisburne"
}
// And so on...
};
var sites = sitesArray.OrderBy(s => s.SiteName);
return Json(sites, JsonRequestBehavior.AllowGet);
}
If you really want to hardcode it, you can do it like this.
Create a class for your ViewModel
public class Site
{
public int SiteID { set;get;}
public string SiteName { set;get;}
}
and in your Action method
public JsonResult GetSites()
{
var list=new List<Site>();
list.Add(new Site{ SiteID=1, SiteName="SiteName 1" } );
list.Add(new Site{ SiteID=2, SiteName="SiteName 2" } );
//13 more times !!!!
return Json(list, JsonRequestBehavior.AllowGet);
}
But Why do you want to HardCode it ? I recommend you to avoid this if at possible.If you are worried about querying your database everytime, you may think about storing the data in a middle Caching Layer and fetch it from there thus avoiding call to database. Think twice.
Suppose the following Employee class (yes I know I shouldn't publicly expose Lists but this is just an example):
class Employee
{
public string Name {get; set;}
public List<string> Skills {get; set;}
}
Skills is just a list of skills the employee has, for example "programming", "customer service", etc.
Now suppose I have a List<Employee> CurrentEmployees, and I also have another employee, Employee NewHire that is not in the CurrentEmployees list.
My goal is to use a lambda expression to count how many employees in CurrentEmployees have at least one skill that NewHire also has. So for example, if CurrentEmployees contains one employee with Skills{'Programming', 'Troubleshooting'}, and another employee with Skills{'Accounting','Finance'}, and NewHire has Skills{'Programming','Networking'}, I would want an expression that returns 1, because the first employee in the list also has 'Programming' as a skill... is this possible?
Thanks for any help.
currentEmployees.Count(ce =>
ce.Skills.Intersect(newHire.Skills).Any())
var currentEmployees = new List<Employee>
{
new Employee { Skills = new List<string> { "Programming", "Troubleshooting" } },
new Employee { Skills = new List<string> { "Accounting", "Finance" } },
};
var newHire = new Employee { Skills = new List<string> { "Programming", "Networking" } };
var count = currentEmployees.Count(e => e.Skills.Any(newHire.Skills.Contains));
// count == 1
If performance was important, I would use a HashSet<string>:
var newHireSkills = new HashSet<string>(newHire.Skills);
var count = currentEmployees.Count(e => e.Skills.Any(s => newHireSkills.Contains(s)));
I used myGeneration in some projects; I noticed that BusinessEntity keeps the result of the query in a DataTable,
But what if the developer wants to get the result as List of objects?
To solve this, I made the following modification for my own use.
public class BusinessEntity
{
//....
public DataTable TheDataTable
{
get
{
return _dataTable;
}
set
{
_dataTable = value;
}
}
public void PutTheRow(DataRow pRow)
{
DataRow newRow = _dataTable.NewRow();
newRow.ItemArray = pRow.ItemArray;
_dataTable.Rows.Add(newRow);
_dataRow = newRow;
//Rewind();
_dataTable.AcceptChanges();
}
.......
}
Now suppose we have a table "Employee" and we generate a class for him, also I make the following modification:
public abstract class Employee : _Employee
{
public Employee()
{
}
public List<Employee> AsList()
{
List<Employee> list = new List<Employee>();
Employee businessEntity = null;
foreach (System.Data.DataRow row in TheDataTable.Rows)
{
businessEntity = new Employee();
businessEntity.TheDataTable = TheDataTable.Clone();
businessEntity.PutTheRow(row);
list.Add(businessEntity);
}
return list;
}
}
Now I can Get a list of objects, from the result of the query, instead of one object and the result in the data table :
Employee employee = new Employee();
employee.Where.ID.Operator = WhereParameter.Operand.NotIn;
employee.Where.ID.Value = "1,2,3";
employee.Query.Load();
foreach (Employee employeeLoop in employee.AsList())
{
TreeNode node = new TreeNode(employeeLoop.s_ID);
node.Tag = employeeLoop;
mMainTree.Nodes.Add(node);
}
Then I can access the selected Employee as following:
Employee emp = (Employee) mMainTree.SelectedNode.Tag;
emp.Name = "WWWWW";
emp.Save();
thanks.
Do You have a better tips, Ideas?
for more discussion, please visit MyGeneration forum.
Why would you create a method called AsList() that only ever returns one Item? You could just create a generic extension method like this (created from the top of my head..):
public static List<T> AsList(this T item)
{
return new List<T>() { item };
}
There is no point to loop through the Employee List of one to add it to a TreeNode.