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?
Related
I have a table called PCRStatusLog with a column called PromoteDate. This column is fed a date where data from an excel sheet was sent from staging to the primary database. It's a new column, hasn't been used yet so for most records it is null, but we need to display the data of this column to our webapp. Most of the logic to do so already exists and the models are ADO.NET entity models generated from EF Designer From Data Base in Visual Studio.
In the table, PromoteDate is DATETIME and nullable (SQL Server) and the model for the table looks like this:
public partial class PCRStatusLog
{
// ... list of fields and properties
public Nullable<System.DateTime> PromoteDate { get; set; }
}
And was generated code, not entered manually. There's nothing special about that class, it's only a list of getters/setters that map to a table, a typical simple entity model.
Here is where it is used (I didn't write most of this code, I only added changes concerning the PromoteDate):
public List<PCRTracking> GetPCRTrackingDetails()
{
//...
List<PCRTracking> pcrDetails = (from bulk in providerMasterContext.BULK_UPLOADS
join ps in providerMasterContext.PROCESSSTATUS on bulk.ProcessStatusID equals ps.ProcessStatusID
join p in providerMasterContext.PLANs on bulk.PlanCode equals p.PlanCode
where bulk.CreateDate > compDateTime
orderby bulk.BulkUploadID descending
select new PCRTracking
{
FileID = bulk.BulkUploadID,
FileName = bulk.BulkUploadActualFileName,
PlanName = p.PlanCode,
FileStatus = string.Empty,
RecordsSubmitted = 0,
RecordsFailed = 0,
ValidationStatusReports = string.Empty,
ErrorMessage = string.Empty,
Submitter = bulk.SubmissionByID,
SubmitterName = bulk.SubmissionByName,
SubmitDate = (DateTime)bulk.SubmissionDateTime
}).ToList<PCRTracking>();
foreach (PCRTracking item in pcrDetails)
{
var promoteDateQuery = (from psl in providerMasterContext.PCRStatusLogs
where psl.BulkUploadID == item.FileID
select psl).FirstOrDefault();
item.PromoteDate = promoteDateQuery.PromoteDate;
//... rest of the code doesn't make use of PromoteDate
All of the other fields in PCRTracking object work fine, but PromoteDate keeps coming up as null, even on the one record that I manually edited to have a date.
Even here, where I examine the object returned by querying the one record I know has a date under promote date, it turns out null:
// from the Main method of a test console project
var providerMasterContext = new BulkPCRDAL().providerMasterContext;
var query =(from psl in providerMasterContext.PCRStatusLogs
where psl.BulkUploadID == 43
select psl).FirstOrDefault();
foreach(var prop in query.GetType().GetProperties())
{
Console.WriteLine(prop.GetValue(query));
}
Console.ReadLine();
It grabs all the properties on the object, and everything looks right, and matches whats in the database, except this one PromoteDate property.
Am I missing something?
Note that everything else in this model works, all other fields display data from the db, this one field is the only one that won't work.
How do you save "Value" and "DataServiceCollection" objects that are part of another SharePoint list item? These are the only properties in my model that are not getting saved.
The generated Food SharePoint model has these sort of properties:
public class Food
{
DataServiceCollection<FoodIngredientValue> Ingredient;
FoodStateValue State;
string _StateValue
}
First, I don't know why there are two ways to add a state value in the model generated by SharePoint. I try populating either one and the state value doesn't populate in SharePoint.
Secondly, I tried populating the Ingredient collection through hard coding FoodIngredientValue objects to the food model before saving and also by querying SharePoint and assigning them to the Ingredient property but it doesn't get saved in SharePoint.
I add a new food item to the SharePoint list using the code below and I verified all three properties are populated in my model but none of them get saved.
public bool Insert(Food food)
{
var dataContext = new FoodDataContext(new Uri(EndpointUrl)) { Credentials = CredentialCache.DefaultNetworkCredentials };
dataContext.AddToFoods(food);
var response = dataContext.SaveChanges().FirstOrDefault();
return response.StatusCode == 201;
}
This was a great blog post explaining how to link complex list items (DataServiceCollecton and Value objects) in the SharePoint oData API:
http://blog.heeresonline.com/2014/07/sharepoint-wcf-dataservices-choice-lookup-column-editing/
The important thing to remember is to add the new item to the data context before you begin populating complex fields of type DataServiceCollection or Value objects. In the case of properties of type DataServiceCollection, there is a little more work that needs to be done to link them properly so they are saved in the data context as shown below for Ingredient. Here is an example of the code that finally worked:
var foodItem = new FoodItem();
dataContext.AddToFoods(foodItem); // Add to context before populating fields so the values are tracked.
foodItem = Mapper.Map(newFood, foodItem);
// DataValue Properties like StateValue objects can now be added since it is tracked by the context.
var state = StateValue.CreateStateValue("Montana");
foodItem.StateValue = state;
// Need to link special DataServiceCollection lists like Ingredient using a reference.
if (newFood.Ingredient != null)
{
newFood.Ingredient.ForEach(c =>
{
var ingredient = FoodIngredient.CreateFoodIngredientValue(c);
dataContext.AttachTo("FoodIngredientValue", ingredient);
foodItem.FoodIngredient.Add(ingredient);
dataContext.AddLink(foodItem, "FoodIngredient", ingredient);
});
}
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
}
}
I'm working with ASP.net Web Service C#.net3.5 and using the LINQ TO SQL to manipulate with SQL DataBase
and I want to return all the countries information from Countries Table,
so I wrote a web method that return a List of object, each object have two data field Country_Id, Country_Name and here is the method :
public List<CountryObject> ReturnAllCountries()
{
ProjectTwoDataBaseDataContext DataBase = new ProjectTwoDataBaseDataContext();
var Country = from a in DataBase.Countries
select new {a.Country_Id,a.Country_Name };
CountryObject TempObject = new CountryObject();
List<CountryObject> TempList = new List<CountryObject>();
foreach (var a in Country)
{
TempObject.setCountry_Id(a.Country_Id);
TempObject.setCountry_Name(a.Country_Name);
TempList.Add(TempObject);
}
return TempList;
}
but when I run the code I get a List that contains the same Object, and this object have the values that get from the last round of Foreach.
I try the Following :
public List<CountryObject> ReturnAllCountries()
{
ProjectTwoDataBaseDataContext DataBase = new ProjectTwoDataBaseDataContext();
var Country = from a in DataBase.Countries
select new {a.Country_Id,a.Country_Name };
CountryObject TempObject;
List<CountryObject> TempList = new List<CountryObject>();
foreach (var a in Country)
{
TempObject = new CountryObject();
TempObject.setCountry_Id(a.Country_Id);
TempObject.setCountry_Name(a.Country_Name);
TempList.Add(TempObject);
}
return TempList;
}
and I get what I want >> WHy ????
The two loops do very different things:
In the first example, you're only creating one object/ Then every time through the loop, modifying the same object, then re-adding it to the list. So your list contains a bunch of references to the same object, over and over again.
This happens because CountryObject, like all classes is a reference type. When you add the instance to TempList you are only adding a reference to that instance, not a copy of it, so when you later modify the instance, those changes will be reflected in the list because it only has a reference to the same instance.
In the second example, creating a new object on every iteration and adding that newly created object to the loop.
Because you're creating a new instance every time, the instances which the list references are not getting modified.
Further Reading
Value Types and Reference Types
Your first code snippet only creates one object that you put into the list multiple times. The second creates one per iteration of the foreach loop.
On another note I would suggest changing CountryObject to have Id and Name properties and you won't need to use an anonymous class in the Linq query. Properties are preferable over get and set methods.
public class CountryObject
{
public int Id { get; set; }
public string Name { get; set; }
}
public List<CountryObject> ReturnAllCountries()
{
ProjectTwoDataBaseDataContext DataBase = new ProjectTwoDataBaseDataContext();
var Country = from a in DataBase.Countries
select new CountryObject{Id=a.Country_Id, Name=a.Country_Name };
return Coutry.ToList();
}
I have two entites with association. I create a dataGridView by drag and drop from objects Data Source and manually binding from to list. Everything works fine with one entity. Is there any possibility of create one dataGridView with two entities(Zamow and ZamSkany) by drag and drop + manually filling? I can do this by view (on SQL side) but in same cases I'd like to have other possibilities.
pg = new PGEntities();
BindingList<Zamow> myList;
var query = (from zam in pg.Zamow where zam.Rok == 2012 select zam).Take(100);
MyList = new BindingList<Zamow>(query.ToList());
zamowBindingSource.DataSource = MyList;
Yes, try to create Class, let say a ViewZamowAndSamSkany
public class ViewZamowAndSamSkany
{
public string Data { get; set; }
public string Proforma { get; set; }
//and Others Properties
}
and now, rebuild your project and from the Objects Data Source add the ViewZamowAndSamSkany then drag-drop to your Form as a DataGridView and you can apply the linq-entites inner join
var query = (from zam in pg.Zamow
join skany in zam.NUMBER equals skany.NUMBER
where zam.Rok == 2012
select new ViewZamowAndSamSkany
{
Data = zam.Data,
Proforma = zam.Proforma
}).Take(100);
MyList = new BindingList<ViewZamowAndSamSkany>(query.ToList());
zamowBindingSource.DataSource = MyList;