assign object from the list using its index - c#

If I have list of Author objects like
List<Author> authors = new List<Author>{
new Author { Id = 1, Name = "John Freeman"};
new Author { Id = 1, Name = "Adam Kurtz"};
};
this example is actually wrapped in static method which returns list of authors.
Inside my other object there is property Authors of type List<Author>.
Now I want to assign second author from the list to Authors property.
I thought that I can use Authors = GetAuthors()[1].ToList();
but I cannot access ToList() on index specified author.
to clarify
private static List<Author> GetAuthors() return list of authors (example above).
var someObject = new SomeObject()
{
Authors = // select only Adam Kurtz author using index
// and assign to Authors property of type List<Author>
};

If I understand you correctly, you want a List<Author> with a single author in it. Using ToList() on a single Author object is then not valid syntax.
Try this: Authors = new List<Author>() { GetAuthors()[1] };

You can't assign a single author to list<Author>, so you will have to create a list (of single author) to assign it..
Authors = new List<Author>() {GetAuthor()[1]};
I don't know, why you want to take based on index, ideally you should write a query based on ID of author to get value, so that it won't create any issue in future..
Like: Authors = new List<Author>() {GetAuthor().FirstOrDefault(x=>x.ID==2)};

A sollution with LINQ would be
GetAuthors().Skip(1).Take(1)
Edit: Ignore all that. You're working with lists.
What you actually need is to use GetRange:
GetAuthors().GetRange(1,1);

Related

Check if List<Dynamic> is contain a object

I have some object with different properties. And i want to store to List using List<dynamic> and i already did.
But i have some problem when try to find specific object what I need.
For example:
I have 2 object Movie and Genre
Movie Object
Movie movie = new Movie()
{
Title = Title,
Description = Description
};
Genre Object
Genre genre = new Genre ()
{
Name = Name
};
And i store like this :
List<dynamic> dynamics = new List<dynamic>();
dynamics.Add(movie);
dynamics.Add(genre);
I dont know to check the list is a movie or genre
I dont want use like dynamics[0] for get Movie object. because i have a lot more object than code below.
I try to use LINQ but did work or i miss something
Best solution is splitting to two collections. If you can not split you can do it in runtime every time dynamics.Where(x=>x.GetType() == typeof(Movie)).Cast<Movie>()

Update All References to Cached Object in Dictionary

I have a simple cache of objects:
Dictionary<int, Person> personCache = ...
personCache.Add(1, new Person(){ID = 1, Name = "John"});
personCache.Add(2, new Person(){ID = 2, Name = "Mary"});
personCache[1].Manager=personCache[2];
(In reality, I have proper encapsulation of the dictionary)
So now John's manager is set to Mary. However, if I want to replace Mary with a new instance of person, if I do
personCache[2] = new Person(){ID = 2, Name = "Kate"});
References to Mary are not replaced with references to Kate - i.e. John's manager is not updated.
I can see why this is - the dictionary has a reference to Kate, but John still holds a reference to Mary.
Can anyone suggest a way such that
personCache[2] = new Person(){ID = 2, Name = "Kate"});
Would have the 'expected' result and replace all references to Mary with a reference to Kate?
I think I need to obtain the reference stored in personCache[2] and change that reference to a new person.
Thank you
Ryan
Why not just search for the Manager directly and updated it where it points to the old value
Person oldPerson = personCache[2];
Person newPerson = new Person() { ID = 2, Name = "Kate" };
personCache[2] = newPerson;
foreach (var pair in personCache) {
if (pair.Value.Manager == oldPerson) {
pair.Vaulue.Manager = newPerson;
}
}
"... Would have the 'expected' result "
I believe it already has what most people would consider to the the expected result.
One way to achieve what you appear to want is to make the Name property of your Person class writable, then do:
personCache[2].Name = "Kate";
Another approach would be to store only the Id of the manager in your Person object, rather than a reference to the Manager. I.e. instead of:
personCache[1].Manager = personCache[2];
You could have:
personCache[1].ManagerId = 2;
And you could, for example, have an extension method to get the Manager for a Person:
public static Person GetManager(this Person person)
{
if (person == null) throw new ArgumentNullException("person");
Person manager;
personCache.TryGetValue(person.ManagerId, out manager);
return manager; // returns null if not found in cache
}

How to assign entity Id to another entity without inserting first entity into database in Entity Framework, C#?

Suppose I have 2 tables with many to one relationship: Book -> Author. Author can have multiple books. So, Book entity has Author and AuthorId navigation properties.
For example Author table contains one row: AuthorName. I want to insert new Author only if the name is unique.
So, what I do:
var book = new Book();
var authorFromDatabase = getAuthorFromDbByName("author name");
if(authorFromDatabase == null)
{
// insert new author if it is not already in the database
book.Author = new Author("author name");
}
else
{
// how to assign AuthorId to book so that it will not add new Author to the db??
// the following line inserts new author into the db
book.AuthorId = authorFromDatabase .AuthorId;
}
So, how can I assign AuthorId to book and not insert a new Author into the db if it's already there?
Setting the .AuthorId property would not create a new Author in the DB - how could it? You're not actually constructing a new Author object and adding it to your DbContext. From what you've given us to look at, it would seem if(authorFromDatabase == null) always resolves as True. Have you debugged the code to ensure that the else block is ever executed?
You should probably show more of of your code, such as your Author and Book entity classes as well as your getAuthorFromDbByName(...) method implementation and where you instantiate your DbContext instances.
If it is about uniqueness I would do something like this:
// some code
newBook.Author = CreateOrGetAuthor("The Name");
// more code
private Author CreateOrGetAuthor(string authorName)
{
var author = _context.Authors.SingleOrDefault(a => a.Name.Equals(authorName, StringComparison.CurrentCultureIgnoreCase));
if (author == null)
{
author = new Author();
author.Name = authorName;
}
return author;
}
Now it depends on if you're using transactions around those both calls. If not, you have to call _context.SaveChanges() first and the return the author in CreateOrGetAuthor. Otherwise it won't have an ID.

Add object to this array of custom Classes C#

This is a noob question, I apologize. I have been trying for a while to figure out how to add an object to this array. I have an Employee class, and a Salary class that inherits from Emp, and an Hourly class that does. I created an array like this,
public Employee[] _Employees;
...
Employee[] _Employees = new Employee[]{
new Hourly("1000", "Harry","Potter", "L.", "Privet Drive", "201-9090", "40.00", "12.00"),
new Salary("2201", "A.", "A.", "Dumbledore", "Hogewarts", "803-1230", "1200"),
new Hourly("3330", "R.","Weasley", "R.", "The Burrow", "892-2000", "40", "10.00"),
new Salary("4040", "R.", "R.", "Hagrid", "Hogwarts", "910-8765", "1000")
};
And now I want to add objects to the array that I have read in from a text file. I am doing it like this right now;
if(rstring == "H")
{
string fullName = data.ReadLine();
string empNum = data.ReadLine();
string address = data.ReadLine();
string phoneNum = data.ReadLine();
string hrWorked = data.ReadLine();
string hrRate = data.ReadLine();
string[] splitName = fullName.Split(new Char[] { ' ' });
string fName = splitName[0];
string mName = splitName[1];
string lName = splitName[2];
_MyForm._Employees = new Employee[] {new Hourly ( empNum, fName, mName, lName, address, phoneNum, hrWorked, hrRate ) };
which doesn't give me any error, but when I look at what is stored in the _Employees class, it just has the info from above and nothing else. Let me know if I need to explain myself better. Just let me know if I need to go about it another way, or what I need to do to add the read info to this _Employees class.
Instead of having an array, you should consider using a List<Employee>. This will let you add any number of elements to the list, without recreating it yourself:
private List<Employee> employees = new List<Employee>();
public IList<Employee> Employees { get { return this.employees; } }
// ...
this.employees.Add(new Hourly("1000", "Harry","Potter", "L.", "Privet Drive", "201-9090", "40.00", "12.00"));
// .. Add all
Then, when you want to add a new one, you can use:
_MyForm.Employees.Add(new Hourly ( empNum, fName, mName, lName, address, phoneNum, hrWorked, hrRate));
You'd be better off using a List in this case:
IList<Employee> _Employees;
List has the advantage of having an Add method which can be used to add new objects to the end of the array.
_MyForm._Employees.Add(new Hourly(...))
If you wanted to insert objects at other points in the collection there's also the Insert method which takes an index along with the object to be added.
Use the List class as others have pointed out and the Add method. What you have done here:
_MyForm._Employees = new Employee[]
in your example code is you've re-assigned your reference of MyForm._Employees to a new object of type Employee[], not added to it. Your previous reference containing your other valuable employees will have most likely been garbage collected (if nothing else in scope is referencing it).
I would steer clear of arrays to be honest. See this for more information.

How to define a collection of my class in C#?

I have encountered a problem on how to define a two dimensional list(or array). Here is my data:
line1 line2 ... lineN
element1: name, phone, addr element1: name, phone, addr
element2: name, phone, addr element2: name, phone, addr
... ...
elementN: name, phone, addr elementN: name, phone, addr
The problem is that we don't know the exact lines and elements in each line. I tried to define the class People, containing members of name, phone, addr, etc, and use:
list<People> info = new list<People>();
That only defined one line - how can I define multiple lines?
People person = new People;
person.Address = "Address";
person.Phone = "11111";
List<People>() info = new List<People>();
info.Add(person);
will add a new instance of your People class (although Person would be a better name)
or potentially better would be a Dictionary with a suitable key
I'm not really sure what you are after but how about a list of dictionary, i.e. List<Dictionary<string, object>>? This will allow you to represent each person as a dictionary with a differing number of attributes.
Ok, after your question was edited is this what you are after: List<List<People>>?
You should have something like:
class SomePeople
{
SomePeople()
{
people = new list<People>();
}
public list<People> people;
}
List<SomePeople> info = new List<SomePeople>();
Or something like that, you get the point...
Try to use indexers here is the link from Microsoft Development Center http://msdn.microsoft.com/en-us/library/6x16t2tx.aspx || http://msdn.microsoft.com/en-us/library/2549tw02.aspx
Another alternative would be to use a list of arrays, so you would declare :
List<People[]> peopleList = new List<People[]>();
And then use it like so :
peopleList.Add(new People[2]
{
new People { name = "name", phone = "123"...},
new People { name = "name", phone = "123"...}
});
peopleList.Add(new people[3]
{
// x 3 initializers
});
Hope that is equally as helpful!
Create a PeopleCollection class that extend Collection:
public class PeopleCollection : Collection<People>
{
}
It provides the base class for a generic collection. From msn documentation: The Collection class provides protected methods that can be used to customize its behavior when adding and removing items, clearing the collection, or setting the value of an existing item. (http://msdn.microsoft.com/en-us/library/ms132397.aspx)
Then you can define a list of People Collection, or a Dictionary, it depends on your object's access need. Like:
List morePeoples = new List();
Here you can put more "line", as you have described. Each "line" (list element) contains a collection of peoples.

Categories