C# Entity Framework and list of objects - c#

I'm using first time entity framework.
I'm developing console application.
I have list of objects and one object contains two string variables: carName and carStatus.
I have database, which have one table, which contains ID and Name.
How I can compare this list to entity set?
I want to know, if database do not contain carName, so I can add it to database.
Here is some of my code:
List<Cars> car = new List<Cars>();
// adding new objects to list.
car.Add(new Cars(carName, carStatus);
// Entity
CarEntities db = new CarEntities();
foreach (var car in db.vehicles)
{
// print out all vehicles in database...
Console.WriteLine(car.Name.ToString());
}

You can use Any method:
using(CarEntities db = new CarEntities())
{
if(!db.vehicles.Any(v => v.Name == "carName"))
{
// add new car to db
}
}

Related

Linq sorts list in object initializer

Today I've faced one very strange behavior. After creating an object with Linq query and object initializer with setting property of List<string> type the original collection and the collection that the object contains have different entries order.
public class PrintHeaderModel
{
public List<string> Ships { get; set; }
}
...
var shipsList = new List<string>() { /* some items */ };
var model = (from inv in db.invoices
where inv.ListID == id && inv.RealmID == realmId
select new PrintHeaderModel()
{
Ships = shipsList,
}).FirstOrDefault();
After that the orders of entries in model.Ships and shipsList are different
Notes:
db is DbContext instance (I'm using Entity Framework and MySQL database)
shipsList is not sorted after it's filled
If I create model object without Linq (just with "new"), the order of entries is the same in model and in the list
The order becames correct if I reassign model.Ships right after model is created:
model.Ships = shipsList; // after that the order of entries is correct
The order of entries in model.Ships is not the same always. It changes randomly without any changes in code or database
Where was I wrong?

Entity Framework, Seeding on Foreign Keys

My question is, can you easily seed a third tier of data using entity framework. I know two tiers of foreign key work as I use them all the time, though will three?
My data structure is the following.
Top Level Table
Table One - Company (One to many of Areas)
- "list" Areas
Table Two - Areas (One to many Items)
- "list" Items
Table Three - Items (Many to One)
- ItemID
Currently the syntax for two levels (Between Company and Areas) works fine:
var NewCompany = new Company() {
Areas = new List<Area>(){
Areaid = 0
}
}
_context.Company.Add(NewCompany);
_context.Areas.AddRange(NewCompany.Areas);
The question is how to achieve the following, adding the third table as a list to Areas.
var NewCompany = new Company() {
Areas = new List<Area>(){
Items = new List<Items>(){
itemId= 1
}
}
}
_context.Company.Add(NewCompany);
_context.Areas.AddRange(NewCompany.Areas);
_context.Areas.AddRange(NewCompany.Areas.Items);
Ideally if you specified the constraint well in database and configured the model correctly then you would not require to add the related entities (Area & Items) to the relavant entity collection.
var NewCompany = new Company() {
Areas = new List<Area>(){
Areaid = 0
Items = new List<Item>(){
new Item(1),
new Item(2)
...
...
}
}
}
//just add newCompany instance to the entity collection rest should be automatically taken care.
_context.Company.Add(NewCompany);
//no need to write below statement.
//_context.Areas.AddRange(NewCompany.Areas);

Removing many to many entity Framework

There is a many to many relationship between Artist and ArtistType. I can easily add artist ArtistType like below
foreach (var artistType in this._db.ArtistTypes
.Where(artistType => vm.SelectedIds.Contains(artistType.ArtistTypeID)))
{
artist.ArtistTypes.Add(artistType);
}
_db.ArtistDetails.Add(artist);
_db.SaveChanges();
This goes and updates the many to many association table with correct mapping. But when I try to remove any item from table I do not get any error but it does not remove it from the table?
foreach (var artistType in this._db.ArtistTypes
.Where(at => vm.SelectedIds.Contains(at.ArtistTypeID)))
{
artistDetail.ArtistTypes.Remove(artistType);
}
this._db.Entry(artistDetail).State = EntityState.Modified;
this._db.SaveChanges();
What am I missing?
Standard way is to load the artist including the current related types from the database and then remove the types with the selected Ids from the loaded types collection. Change tracking will recognize which types have been removed and write the correct DELETE statements to the join table:
var artist = this._db.Artists.Include(a => a.ArtistTypes)
.SingleOrDefault(a => a.ArtistID == someArtistID);
if (artist != null)
{
foreach (var artistType in artist.ArtistTypes
.Where(at => vm.SelectedIds.Contains(at.ArtistTypeID)).ToList())
{
artist.ArtistTypes.Remove(artistType);
}
this._db.SaveChanges();
}
For removing only one field, I came up with this solution. It seems odd but in EF, most of the things are odd anyway because we try to tell EF the database ops in terms of OOP.
using (var db = new Context())
{
//Create existing entities without fetch:
var artist = new Artist() { ArtistID = _artistID };
var type = new Type() { TypeID = _typeID };
//Add one entity to other's list
//This is in memory, not connected.
//So we do this because we try to tell EF that we want to remove this item
//Without fetch, we should add it first in order to remove :)
artist.ArtistTypes.Add(type);
//Attach that entity which you add an item to its list:
db.Artists.Attach(artist);
//It's now connected and recognized by EF as database operation
//After attaching, remove that item from list and save db
artist.ArtistTypes.Remove(type);
db.SaveChanges();
}
That's it! With this solution, you are no longer fetching all entries of joined table ArtistTypes.

Crm 2011 - retrieve associated [N:N] entities (C#)

I'm writing a simple application that imports entities to CRM. Durring this import I need to associate imported entities (custom entity) to another (also custom) entities.
There's no problem with new objects, but when I try to update, I need to delete all associations regarding imported entity and recreated them based on imported data.
How can I do this?
I was thinking of getting all associated entities, and then call disassociate for each of them, but I got stuck trying to get those associated entities.
How should I approach this?
Suppose that you have Student Entity And you want to copy the student Cources to another custom Entity as you said named CStudent
You can use the following code:
var scs = Context.new_Student_CourcesSet.Where(x => x.new_courceid == Cource.Id).ToList<new_Student_Cources>();
var removedsc = Context.new_new_CStudent_CourcesSet.Where(x => x.new_cstudentid == CStudent.Id).ToList<new_CStudent_Cources>();
EntityReferenceCollection relatedEntities = new EntityReferenceCollection();
EntityReferenceCollection removedrelatedEntities = new EntityReferenceCollection();
Relationship relationship = new Relationship(new_CStudent_Cources.EntityLogicalName);
if (removedsc != null)
{
foreach (new_CStudent_Cources c in removedsc )
{
RemovedrelatedEntities.Add(new EntityReference(new_Cources.EntityLogicalName, (Guid)ar.new_courcesid));
}
Service.Disassociate(CStudent.LogicalName, CStudnetid, relationship, RemovedrelatedEntities);
}
foreach (new_Student_Cources d in scs)
{
relatedEntities.Add(new EntityReference(new_Cources.EntityLogicalName, (Guid)d.new_courceid));
}
Service.Associate(CStudent.LogicalName, CStudentid, relationship, relatedEntities);

Save a relation with between two entities an N-N association

I've a Entity Framework 4.0, with poco object. the edmx model file is generated from the database.
This datacontext is accessed through WCF service, it's only mean that I receive some objects and I need to attach them to the current datacontext(or reload them with the key correspondance).
Everything seems to work fine, except for one case:
I've a N-N relationship between two table, so I've an association table, without any field other than ID of two tables:
LINQ transform this into the following schema, this seems to be right.
When I retrieve data, there is no problem, data I've inserted myself in the Right_group are correctly transformed into "new object in my collection of Rights/Groups".
But if I try to modify something and save, it doesn't work
public void SaveRights(Group group, List<Rights> rights){
//here, group and rights are objects attached to the database
group.Rights.Clear();
group.Rights.AddRange(rights);
_dataContext.SaveChanges();
}
So my question is: How to save this "relationship" of two objects ?
Thank you!
If you want to avoid loading the objects from the database first you can do it like this(Code taken from one of my aplications so you will have to adapt it):
public void AddAndRemovePersons(int id, int[] toAdd, int[] toDelete)
{
var mailList = new MailList { ID = id, ContactInformations = new List<ContactInformation>() };
this.db.MailLists.Attach(mailList);
foreach (var item in toAdd)
{
var ci = new ContactInformation { ID = item };
this.db.ContactInformations.Attach(ci);
this.db.ObjectStateManager.ChangeRelationshipState(mailList, ci, ml => ml.ContactInformations, System.Data.EntityState.Added);
}
foreach (var item in toDelete)
{
var ci = new ContactInformation { ID = item };
this.db.ContactInformations.Attach(ci);
this.db.ObjectStateManager.ChangeRelationshipState(mailList, ci, ml => ml.ContactInformations, System.Data.EntityState.Deleted);
}
}
I found deleting the relationship as hard as creating it so I left that code in there. One thing about this solution is that both the maillist and the contacts exist prior to this function being run. I attach them to make the state manager track them.
If you are adding new objects that you also want to save you would use the
this.db.MailLists.AddObject(you new item here)
I hope that helps!
Just a thought... how are the keys setup in the Right_Group table? If you use both IDRight and IDGroup together as primary key - this problem might occur. One suggetion is to add a new column (ID) into the Right_Group table, and having this ID as the primary key. Then use foreign keys on the other columns (IDRight, IDGroup) respectivly.

Categories