C# datatable Entity Framework - c#

I have two objects people and house, and I want to show the table people in a datagridview, but in the field House, the value shown is Program.Model.House; I want to show the street name instead, how I can do it? (I'm using Entity Framework and the data source of data grid view I use context.tolist())
public class People
{
public string Name { get; set; }
public House House { get; set; }
}
public class House
{
public string Street { get; set; }
public int Number { get; set; }
}

Override ToString() in House class. Like that :
public override string ToString(){ return $"Street: {Street}"; }

You wanted to show data like Name and Street Name
For Name You can use Model.Name
For Street Name you can use Model.House.Street
For Example
#foreach(var item in Model)
{
<td> #Model.Name</td>
<td> #Model.House.Street</td>
}
May this help you

Simply create a new object for grid view with a street name.
List<object> peopleData=new List<object>();
peopleData.Add(new{ ppl.Name,ppl.House.Street });
grdPeople.DataSource = peopleData;```

Related

Creating Complex Automapper

I am trying to use the automapper to map my Database table output to my class object. But the table has 3 rows that are all belong to single employee data which needs to be assigned to a single class object. How we can we create mapper ? Is it possible to create mapper with this table data ?
How can I write Autommapper to populate the class EmployeeDetails
public class EmployeeDetails
{
public string EmpNo { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
public List<Phone> Phone { get; set; }
}
public class Address
{
public string Address_1 { get; set; }
public string City { get; set; }
}
public class Phone
{
public string PhoneType { get; set; }
public string PhoneNo { get; set; }
}
Datatype EmpNo Name Address_1 City PhoneType PhoneNo
Name 1234 Test Test addr Testcity Null Null
Phone 1234 Null Null Null Mobile 123456
Phone 1234 Null Null Null Work 789546
public IEnumerable< EmployeeDetails > GetEmployeeDetails()
{
return ExecuteEmpReader< EmployeeDetails>().ToList();
}
private IEnumerable<T> ExecuteEmpReader <T>()
{
DataTable dt=new Datatable();
//Assume the dt will be loaded as per the above table.
foreach (DataRow item in dt.Rows)
{
yield return _mapper.Map<T>(item)
}
}
I don't believe there is a way to do what you want using solely Automapper. Specifically because of the merging of rows into one. This link shows how you can at least unflatten your object to your desired object structure, but then you would need to write the logic to merge the employees addresses and phone numbers yourself.
http://martinburrows.net/blog/2016/01/18/automatic-unflattening-with-automapper
On the contrary to make your resulting code easier to maintain in future. I would recommend creating some views of your Employee Object, one for Employee, one for Address, and one for Phone. Then you can use EF to map your views straight to your objects.

Getting only a part of a specific Ravendb document

Is it possible to load only a part of a Ravendb document.
I want to fetch a document by id, but only some fields should be fetched.
I know I can use session.Query with a Selectcall, but then I can't query on the id of the document so I have to use session.Loadinstead, but this fetches the whole document.
Do I need to create an index for this?
You can use something called Results Transformers to achieve this.
Say you have an entity "Customer"
public class Customer
{
public string Id { get; set; }
public string Name { get; set; }
public Address Address { get; set; }
public string PhoneNumber { get; set; }
public string Email { get; set; }
}
and you want to load only the Id and the Name property, you define a Results Transformer:
public class CustomerNameTransformer : AbstractTransformerCreationTask<Customer>
{
public CustomerNameTransformer()
{
TransformResults = results => from customer in results
select new CustomerNameViewModel
{
Id = customer.Id,
Name = customer.Name
};
}
}
and your "view model":
public class CustomerNameViewModel
{
public string Id { get; set; }
public string Name { get; set; }
}
With this, you can access the Customer entity as a "Customer Name ViewModel" in several ways:
//Load and transform by one id
CustomerNameViewModel viewModel = session.Load<CustomerNameTransformer, CustomerNameViewModel>("customers/1");
//Load and transform by several id's
CustomerNameViewModel[] viewModels = session.Load<CustomerNameTransformer, CustomerNameViewModel>(new[]{ "customers/1", "customers/2"});
//Query and transform
List<CustomerNameViewModel> viewModels = session.Query<Customer>()
.TransformWith<CustomerNameTransformer, CustomerNameViewModel>()
.ToList();
Results Transformers are executed server side before the data is returned to the client. They are created by the same IndexCreation task that creates the index definitions on the server.
You can read more about Results Transformers in the documentation:
http://ravendb.net/docs/article-page/2.5/csharp/client-api/querying/results-transformation/result-transformers
Hope this helps!

Create View With One-Many Relationship

I have 2 simple models:
public class Country
{
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Region> Region { get; set; }
}
public partial class Region
{
public int ID { get; set; }
public string Name { get; set; }
public int CountryID { get; set; }
public virtual Country Country { get; set; }
}
Is it possible to have a single page to handle the creation of a country whereby the user inputs the country with multiple regions and then only posts to the server?
I've seen an implementation here where you create a custom ViewModel with numbered properties (Region1, Region2, Region3, etc) but it's limiting, any suggestions?
(I know AngularJS can be used to do this however I have no experience in this space as of yet.)
Thanks
Yes its very possible it just depends on how you plan to implement this.
My favourite style of implementing One to Many pages is initially creating the "one" (country) then redirecting to a page with a grid element where users can add the many (regions) to the one. It works well and its a very easy way for both the programmer to create and the user to understand.
As for creating a country with multiple regions in a single post, it could be done but you must think of how the implementation will work.
Sure, this is easy to do. You have defined your data model. Either you use that also as your View Model, or you can create a new model that is a complex object. The methods in your type:
public virtual Country Country { get; set; }
public virtual ICollection<Region> Region { get; set; }
These method being present normally indicates you're using Entity Framework and that these are "related entities" that you can traverse via this "navigation property" at run-time. You can create a Country and populate the Region collection on the fly when you try to use it.
Here is a good example of using a View Model:
What is ViewModel in MVC?
///Example of a Controller method creating a view model to display
[HttpGet]
public ActionResult Index()
{
var user = _userService.Get(User.Identity.Name);
var customerId = GlobalDataManager.GetCustomerId();
if (_error != null)
{
ModelState.AddModelError("", _error);
_error = null;
}
var model = new InboundListModel();
model.Initialize(customerId, user.CompanyId);
foreach (var campaign in model.Campaigns)
{
model.InitializeCallProggress(campaign.Id, _callInfoService.GetCallsCount(campaign.Id));
}
return View(model);
}
This View Model can be anything you want but it does need to be one type. So if you want 2 put 2 types in the ViewModel you just need a new container object:
public class ComplexViewModel
{
public Country Country { get; set; }
public ICollection<Region> Regions { get; set; }
}
Then you just need a way to populate the data like the example above where I call Initialize. This goes out to EF via a DAL project and retrieves the data for the model.

How to Store a list of Design-Time data

I have the following structure in my data:
Category0
-SubCategory0
-SubCategory1
-SubCategoryN
Category1
-SubCategory1_0
-SubCategory1_1
-SubCategory1_N
A category will have a NAME, a Description and a Unique Integer ID
e.g.
Category = Ford Description = "USA Car" Id = 12345678
-SubCategory: Name = Mondeo Description = "Some text" Id = 12324
-SubCategory: Name = Fiesta Description = "Some text" Id = 9999
-SubCategory: Name = Orion Description = "Some text" Id = 123456
-SubCategory: Name = Focus Description = "Some text"Id = 8799
The list is known at design time and I need to bind to the listview. I'd like to bind the Description as the Display Text on each line of the listview and the values(an object or an enum with the Name and Id) as the corresponding valuemember.
What is the best method to store this info? Should I create a large number of enumerations? Or should I bind directly to the listview in designer mode using delimited strings such as "Ford:Mondeo:Some Text: 12324" and then parse and extract as needed. Perhaps it would be better to have the data stored strongly typed enums with custom attributes for the id/description values e.g bind to a dictionary where string is a description and CarType is a class with properties: Make(Ford):enum, Model(Modeo):enum and Id(12324):int?
Typically you would model this with two classes:
public class Model
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
public class Manufacturer
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public List<Model> Models { get; set; }
}
If you are concerned about performance in the comparisons, and you know exactly all the manufacturer and model names, you should consider changing the names into enums.
Also, if you will be accessing these items by name, you should consider keeping them in a dictionary with the name as the key.
This sounds like a perfect use for XML. You can add / remove categories, change the values of the name & description etc. Parse it into a simple class structure...
public class ParentCategory : Category
{
public List<Category> SubCategories { get; set; }
}
public class Category
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
And then you simply bind these classes to your view.
Just because it's known at design time is not a good enough reason to go and create tons of duplicated, redundant code. It makes your program so much harder to maintain. Yes, it's simpler to look at for someone uncomfortable with XML (or any data file) but if something changes - you need to add another property to the categories, for example - you'll need to go and change every single class / enum. Messy and tedious.
edit: Just to clarify, when I say XML that's just my preferred format. You can also store your data as text, CSV, whatever your favourite format. I prefer XML as it's easier to work with.
edit2:
I see your concern (if(carListView.SelectedValue == "Mondeo")). Without knowing (or wanting to know) your whole system or what you're trying to do, I'd prefer to work in a more generic, object focused fashion.
So you'll need an if statement for each type of car? Why not just get the car to do its own work?
public class ParentCategory : Category
{
public List<Category> SubCategories { get; set; }
public void DoThings()
{
// look at SubCategories, print something, etc
}
}
// and then get the item to do things!
((ParentCategory)carListView.SelectedValue).DoThings();
This way there's no looping through whole lists. Again, keep your number of lines down.

Asp.Net MVC Handle Drop Down Boxes that are not part of the Model

I have a small form which the user must fill in and consists of the following fields.
Name (Text)
Value (Text)
Group (Group - Is a list of option pulled from a database table)
Now the Model for this View looks like so,
public string Name { get; set; }
public string Value { get; set; }
public int GroupID { get; set; }
Now the view is Strongly Typed to the above model.
What method would one use to populate the drop down list? Since the data is not contained within the Model (It could be contained in the Model) should we be using Temp/View data? A HTML Helper? What would be the ideal way to achieve this.
I use a viewmodel for this with a dictionary (I like mvc contrib's select box) containing all the properties something like:
class LeViewModel {
public string Name { get; set; }
public string Value { get; set; }
public int GroupID { get; set; }
public Dictionary<string, string> Groups {get; set;}
}
Then in your view you'll only need to do
<%: Html.Select(m => m.GroupId).Options(Model.Groups) %>
Hope it helps.
NOTE: this assumes you are using MVC2.
If I ever need a strongly typed drop-down (a list of countries in this case), I use 2 properties on my ViewModel.
public IEnumerable<SelectListItem> Countries { get; set; }
public int CountryID { get; set; }
I do a pre-conversion of my list to an IEnumerable<SelectListItem> in my action using code similar to this. (This assumes a country class with a name and unique ID).
viewModel.Countries = Repository.ListAll().Select(c => new SelectListItem { Text = c.Name, Value = c.ID });
Then in my strongly typed view, I use:
<%= Html.DropDownListFor(model => model.CountryID, Model.Countries) %>
This is great, because when you post back to a strongly typed action (receiving the same viewmodel back), the CountryID will be the ID of the selected country.
The other benefit, if they have an issue with the validation. All you need to do is repopulate the .Countries list, pass the viewmodel back into the view and it will automatically select the the correct value.
I like the following approach: Have a helper class that does this things for you, something like (pseudo):
class DropdownLogic {
public DropdownLogic(MyModel model) { /* blah */ }
public ListOfDropdownItems ToDropdown() {
/* do something with model and transform the items into items for the dropdownlist */
// f.e. set the item that matches model.GroupId already as selected
}
}
Add in your model:
public DropdownLogic Groups { get; set; }
And in your view:
<%=Html.Dropdown(Model.Groups.ToDropdown())%>

Categories

Resources