Are there "Records" in C#? - c#

I'm looking to store some customer data in memory, and I figure the best way to do that would be to use an array of records. I'm not sure if that's what its called in C#, but basically I would be able to call Customer(i).Name and have the customers name returned as a string. In turing, its done like this:
type customers :
record
ID : string
Name, Address, Phone, Cell, Email : string
//Etc...
end record
I've searched, but I can't seem to find an equivalent for C#. Could someone point me in the right direction?
Thanks! :)

Okay, well that would be defined in a class in C#, so it might look like this:
public class Customer
{
public string ID { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string Phone { get; set; }
public string Cell { get; set; }
public string Email { get; set; }
}
Then you could have a List<T> of those:
var customers = new List<Customer>();
customers.Add(new Customer
{
ID = "Some value",
Name = "Some value",
...
});
and then you could access those by index if you wanted:
var name = customers[i].Name;
UPDATE: as stated by psibernetic, the Record class in F# provides field level equality out of the gate rather than referential equality. This is a very important distinction. To get that same equality operation in C# you'd need to make this class a struct and then produce the operators necessary for equality; a great example is found as an answer on this question What needs to be overridden in a struct to ensure equality operates properly?.

A class or a struct would work here.
class Customer
{
string Name
{
get;
set;
}
string Email
{
get;
set;
}
}
Customer[] customers = new Customer[50];
//after initializing the array elements, you could do
//assuming a for loop with i as index
Customer currentCustomer = customers[i];
currentCustomer.Name = "This";

It appears that the "type" you are looking for is actually a Class.
class Customer {
string id, name, phone, cell, email;
}
List<Customer> customerList = new List<Customer>();
Check this link for more detail on classes... you may want to do a bit of research, reading and learning :-)
http://msdn.microsoft.com/en-us/library/vstudio/x9afc042.aspx

Assuming you have a class which models your customers, you can simply use a List of customers.
var c = new List<Customers>()
string name = c[i].Name

Related

C# - Make copy of a big class (model) by value not reference

I do project by asp.net core mvc. when I do copy of the model and change its values, the values of the original model is changing too because it made copy of the model by reference, so the value place in data is same.
I need way that I can do copy for values of the model doesn't connect with original model.
Your question could have many answers depending on the encapsulation of the object you are copying. I will assume you are operating on a low level entity object rather than an object that is supposed to encapsulate it. If this assumption is incorrect and it is a higher level object that encapsulates entity operations I will gently remind you of good programming practices: Martin Fowler - TellDontAsk.
For the answer I will use the class below to illustrate:
public class Student
{
public int Id { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public DateTime EnrollmentDate { get; set; }
}
I assume what is happening is something similar to the following:
Student john = new Student();
Student jane = john;
jane.FirstName = "Jane"; // now john.FirstName == "Jane"
What you are going to need to do is clone the object to a new object instance. There are various ways to do that.
Option #1:
// Create a new entity object manually assigning each value
// from the first object to the value in the new object.
var clonedStudent = new Student
{
Id = john.Id, // Copies value not reference
LastName = john.LastName, // string is immutable this OK
FirstName = john.FirstName, // string is immutable this OK
// DateTime is a struct I think so it should pass value
EnrollmentDate = john.EnrollmentDate // Verify my assumption
};
Option #2:
// Make Student class partial and extend it with clone method.
// This is helpful for generated entities not using the code-first approach.
public partial class Student
{
public int Id { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public DateTime EnrollmentDate { get; set; }
}
public partial class Student
{
public Student Clone()
{
return new Student
{
Id = Id, // Copies value not reference
LastName = LastName, // string is immutable this OK
FirstName = FirstName, // string is immutable this OK
// DateTime is a struct I think so it should pass value
EnrollmentDate = EnrollmentDate, // Verify my assumption
};
}
}
To use it you would write:
Student clonedStudent = john.Clone();
Option #3: You could use a NuGet package that does the cloning for you. There are various ones that do that. A quick google search pulled up this one for me. DeepCloner
If you are copying objects from one type to another you might want to use AutoMapper.
NOTE: Also, based on your question a good knowledge of how entity framework handles changes might be useful.
Tracking vs. No-Tracking Queries
Hopefully that helps.
Happy coding!!!
option 1 use AutoMapper
option 2 create Copy using Reflection
public class PropertyCopier<TParent, TChild> where TParent : class
where TChild : class
{
public static void Copy(TParent parent, TChild child)
{
var parentProperties = parent.GetType().GetProperties();
var childProperties = child.GetType().GetProperties();
foreach (var parentProperty in parentProperties)
{
foreach (var childProperty in childProperties)
{
if (parentProperty.Name == childProperty.Name && parentProperty.PropertyType == childProperty.PropertyType)
{
childProperty.SetValue(child, parentProperty.GetValue(parent));
break;
}
}
}
}
}

Remove columns from list object out of a class c#

I need the possiblity to create Code in C# like this
public class SummaryA
{
public string name { get; set; }
public string surename { get: set; }
public int age { get; set;}
}
now I create an list object from the class SummaryA
List<SummaryA> list1= new List<SummaryA>();
yet I need the possibility to remove the column age from the list Summary, anyone have ideas?
I need this for some more columns, so I wish the list was dynamically or some things else.
sry for my bad english.
To completely remove the column you really need another class to store the data in, for example:
public class AgelessSummaryA
{
public string name { get; set; }
public string surename { get: set; }
}
And now you can project the first list into a new list of this class with Linq and Select:
List<AgelessSummaryA> agelessSummaries = ageSummaries
.Select(s => new AgelessSummaryA
{
name = s.name,
surename = s.surename
})
.ToList();
To use it for in a grid or for some display i guess, then you can use anonymous types where you can shape the data the way you like:
var projectedList = (from l in list1
select new
{
name = l.name,
surename = l.surename
}).ToList();

neo4jclient to POCO objectGraph

I'm starting to play with neo4jclient, and although I have found the wiki pages which show pulling out nodes etc. I'm a little confused how to take a slighlty more complex structure from the graphDB and reconstruct it into my POCO objects.
As an example, say I have the following graph:
And I have the following classes:
public class Person
{
public string name { get; set; }
public List<Sport> watches { get; set; }
public List<Sport> plays { get; set; }
}
public class Sport
{
public string name { get; set; }
public GoverningBody governingBody { get; set; }
}
public class GoverningBody
{
public string name { get; set; }
}
Could somebody give me the c# code I would need to use to pull out "David", along with the sports he plays and the governing body for that sport. The end goal would be that the Person, Sport(s) and GoverningBody objects would all be populated so that I can use them as normal within the C# code.
Thanks
David
This is a very quick solution - you can create (in effect) an anonymous type in the With statement that you can parse into a result, for example, with the addition of a SportAndGovern class:
public class SportAndGovern
{
public Sport Sport { get; set; }
public GoverningBody Govern { get; set; }
}
You can execute this Cypher (I've not used parameterised stuff, you should) to get a person with a list of the sports they play - you do end up with duplicated Governing Bodies coming back, i.e. one for each Sport the person watches.
var query = Client.Cypher
.Match("(p:Person {Name:'David'})")
.OptionalMatch("(p)-[:PLAYS]->(s:Sport)<-[:GOVERNS]-(g:GoverningBody)")
.With("p, Collect(Distinct {Sport: s, Govern: g}) as sportAndGovern")
.Return((p, sportAndGovern) => new
{
Person = p.As<Person>(),
SportAndGovern = Return.As<IEnumerable<SportAndGovern>>("sportAndGovern")
});
This code should get you started
var userQuery = client.Cypher
.Match("(n:Person { name: 'David'})-[:PLAYS]->(s:Sport)")
.Return((n, s) => new
{
Peep = n.As<Person>(),
Sports = s.CollectAsDistinct<Sport>()
})
.Results
.FirstOrDefault();
var david = userQuery.Peep;
david.plays = userQuery.Sports.ToList();
SO looking at this in a little detail there are some points to note.
Firstly, client refers to an instance of Neo4jClient and assumes that you have previously initialised this.
Secondly, the query assumes that you only have one Person node where the name property has a value of "David".
The Return clause projects the query results into an Anonymous type. It uses the CollectAsDistinct method to return an IEnumerable<Sport> collection. This translates into COLLECT(distinct s) in Cypher to collect the Sport nodes.
Finally, it then users the anonymous type to build up a Person object to return.

Best implementation of a searchable GET endpoint in ASP.NET Web Api

I have a WebApi which exposes a Contact field in my database. Currently it has endpoints for Post (create), Put (edit), Get(return whole list), Get(int id) (return specific field).
So the Get(int id) searches my DB for the contact with that id and returns it in JSON. I would like to implement a method by which the user can submit conditions to my first Get function such as:
GET http://urlformyapi.com/api/apiContact/?querystring
Where the query string might be for example:
firstname=phil
And return all the Phil's.
How is best to make this totally searchable for all of my data fields within contact?
public int contactid { get; set; }
[Required]
public string firstname { get; set; }
[Required]
public string lastname { get; set; }
[Required]
public string email { get; set; }
[Required]
public string mobile { get; set; }
public string company { get; set; }
public string position { get; set;}
public string notes { get; set; }
public string image { get; set; }
I could do an initial get of the whole list and then go through each query parameter like:
//where ContactList begins as the entire list of contacts.
if(notes != null){ ContactList = ContactList.Where(x => x.notes == notes).ToList(); }
Thus refining my list until returning it. But I wondered if there was an easier way which was more robust should my data model change/I want to make more fields searchable.
any thoughts?
If you have a lot of similar API methods, you can take a look on OData. Another variant try to use for this purpose Dynamic Linq with custom filter formatting. Otherwise my suggestion is create class which must contains query fields (search fields), for example: notes, ids, etc and then pass this object to API and filter your collections with those search fields and PredicateBuilder. Also good explanation how PredicateBuilder works.

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.

Categories

Resources