Convert GridView to List<object> - c#

Hi and thanks in advance. I'm having a problem implementing a suggestion that I found here: Convert contents of DataGridView to List in C#
I am grabbing a GridView from a Master page and I need to add a row to the table then rebind it. I am accessing the GridView via a public property on the Master page which is being returned with data. So basically I have done this:
var gsr = master.GridSearchResults;
gsr (gsr != null)
{
var so = new List<MyProperties>();
so = gsr .Rows.OfType<DataGridViewRow>().Select(r => r.Cells.OfType<DataGridViewCell>().Select(c => c.Value).ToArray()).ToList<MyProperties>();
so.Add(new MyProperties()
{
Id = id,
Date = date,
Building = buildingName,
Street = streetName
}
gsr.DataSource = so;
gsr.DataBind();
}
But I'm receiving an error that it cannot convert an instance argument type System.Collections.Generic.IEnumerable<'object[]'> to System.Collections.Generic.IEnumerable<'MyProperties'>. I thought the problem was the call to the array but if I remove it then I just get a variation of the same error.

Turns out my issue was that I shouldn't have been getting the gridview in the first place but getting the the Gridview's source which was in session. So I solved it like this:
var master = (Tab)Master;
master.GridSearchResults.DataSource = null;
var sessions = new Sessions();
sessions.SlideOutSource.Add(new MyProperties {
Id = Id,
StartDate = hidStartDate.Value,
Installation = txtInstall.Text,
Command = txtCommand.Text });
master.GridSearchResults.DataSource = sessions.SlideOutSource;
master.GridSearchResults.DataBind();

Related

How to execute RawSql against the context

I currently have a project that I'm working on, which has a database connected to it. In said database I need to query some tables that don't have a relationship. I need to get a specific set of data in order to display it on my user interface. However I need to be able to reference the returned data put it into a list and convert it into json. I have a stored procedure that needs to just be executed against the context because it's retrieving data from many different tables.
I've tried using ExecuteSqlCommand but that doesn't work, because it returns -1 and can't put it into a list.
I've tried using linq to select the columns I want however it's really messy and I cannot retrieve the data as easily.
I've tried using FromSql, however that needs a model to execute against the context which is exactly what I don't want.
public string GetUserSessions(Guid memberId)
{
string sql = $"EXECUTE dbo.GetUserTrackByMemberID #p0";
var session = _context.Database.ExecuteSqlCommand(sql, memberId);
var json = JsonConvert.SerializeObject(session);
return json;
}
This is the ExecuteSqlCommand example, this returns -1 and cannot be put into a list as there will be more than one session.
public string GetUserSessions(Guid memberId)
{
var session = _context.MemberSession.Where(ms => ms.MemberId == memberId).Select(s => new Session() { SessionId =
s.SessionId, EventId = s.Session.EventId, CarCategory = s.Session.CarCategory, AirTemp = s.Session.AirTemp,
TrackTemp = s.Session.TrackTemp, Weather = s.Session.Weather, NumberOfLaps = s.Session.NumberOfLaps, SessionLength = s.Session.SessionLength,
Event = new Event() { EventId = s.Session.Event.EventId, TrackId = s.Session.Event.TrackId, Name = s.Session.Event.Name, NumberOfSessions =
s.Session.Event.NumberOfSessions, DateStart = s.Session.Event.DateStart, DateFinish = s.Session.Event.DateFinish, TyreSet = s.Session.Event.TyreSet,
Track = new Track() { TrackId = s.Session.Event.Track.TrackId, Name = s.Session.Event.Track.Name, Location = s.Session.Event.Track.Location, TrackLength
= s.Session.Event.Track.TrackLength, NumberOfCorners = s.Session.Event.Track.NumberOfCorners} } });
var json = JsonConvert.SerializeObject(session);
return json;
}
This is using Linq, however it's really messy and I feel there's probably a better way to do this, and then when retrieving the data from json it's a lot bigger pain.
public string GetUserSessions(Guid memberId)
{
var session = _context.MemberSession.FromSql($"EXECUTE dbo.GetUserSessionByMemberID {memberId}").ToList();
var json = JsonConvert.SerializeObject(session);
return json;
}
This is the ideal way I would like to do it, however since I'm using the MemberSession model it will only retrieve that data from the stored procedure which is in the MemberSession table, however I want data that is in other tables as well....
public string GetUserSessions(Guid memberId)
{
var session = _context.MemberSession.Where(ms => ms.MemberId == memberId).Include("Session").Include("Event").ToList();
var json = JsonConvert.SerializeObject(session);
return json;
}
I tried this way but because the Event table has no reference / relationship to MemberSession it returns an error.
As I've previously stated in the RawSql example I'm only getting the table data that is in the MemberSession table, no other tables.
There are no error messages.
using (var context = new DBEntities())
{
string query = $"Exec [dbo].[YOUR_SP]";
List<ResponseList> obj = context.Database.SqlQuery<ResponseList>(query).ToList();
string JSONString = JsonConvert.SerializeObject(obj);
}

NEST - IndexMany doesn't index my objects

I've used NEST for elasticsearch for a while now and up until now I've used the regular ElasticSearchClient.Index(...) function, but now I want to index many items in a bulk operation.
I found the IndexMany(...) function, but I must do something wrong because nothing is added to the elastic search database as it does with the regular Index(...) function?
Does anyone have any idea?
Thanks in advance!
I found the problem. I had to specifiy the index name in the call to IndexMany
var res = ElasticClient.CreateIndex("pages", i => i.Mappings(m => m.Map<ESPageViewModel>(mm => mm.AutoMap())));
var page = new ESPageViewModel
{
Id = dbPage.Id,
PageId = dbPage.PageId,
Name = dbPage.Name,
Options = pageTags,
CustomerCategoryId = saveTagOptions.CustomerCategoryId,
Link = dbPage.Link,
Price = dbPage.Price
};
var pages = new List<ESPageViewModel>() { page };
var res2 = ElasticClient.IndexManyAsync<ESPageViewModel>(pages, "pages");
This works as expected. Guess I could specify a default index name in the configuration to avoid specifying the index for the IndexMany call.
If you are using C# you should create a list of objects that you want to insert then call the IndexMany function.
Example :
List<Business> businessList = new List<Business>();
#region Fill the business list
...............................
#endregion
if (businessList.Count == 1000) // the size of the bulk.
{
EsClient.IndexMany<Business>(businessList, IndexName);
businessList.Clear();
}
And in the end check again
if (businessList.Count > 0)
{
EsClient.IndexMany<Business>(businessList, IndexName);
}

Show results based on two items from array or more

I've been struggling for hours now trying to figure out, how to display data based on array items using linq c#.
In short i am displaying data based on results from a querystring that passes into an array.
this works great with one array item.
but if i navigate to another page that has two or more array items, i want to be able to say only show me results that contains x,y,z. Code below:
public static List<business.Resource> getResourcesFromTags(string[] tags)
{
var db = new Entities();
List<business.Resource> resources = (
from rt in db.tbl_ResourceTag
where tags.Any(t =>t.Equals(rt.tbl_Tag.Name))
select new Resource {
bookmark = rt.tbl_Resource.Bookmark,
dateAdded = rt.tbl_Resource.dateAdded,
text = rt.tbl_Resource.text,
uploadedFile = rt.tbl_Resource.uploadedFile,
uploadedImage = rt.tbl_Resource.uploadedImage,
resourceID = rt.tbl_Resource.ResourceID,
filePath = rt.tbl_Resource.filePath,
imagePath = rt.tbl_Resource.imagePath,
downloadCount = rt.tbl_Resource.downloads
}).Distinct().ToList();
return resources;
}
So to re-cap if there is more than one array item, i want to be able to show data contains just those items. very difficult to explain.

How to prevent duplicate record on run time

This code cause double record...
i checked my insert code for all tables and it works fine...
and this is insert code:
StoreDO store = new StoreDO();
List<BrandDO> brandList = new BrandBL().SelectBrands();
StoreBL storeBL = new StoreBL();
store.StoreName = txtStoreName.Text;
store.StorePhone = txtStorePhone.Text;
store.StoreAddress = txtStoreAddress.Text;
store.CityID = int.Parse(ddlCity.SelectedValue);
store.CountyID = int.Parse(ddlCounty.SelectedValue);
store.IsActive = chkIsActive.Checked;
int storeID = storeBL.InsertStore(store);
ContentPlaceHolder contentPlaceHolder = (ContentPlaceHolder)Master.FindControl("ContentPlaceHolder1");
for (int i = 0; i < brandList.Count; i++) {
string brandName = brandList[i].BrandName.ToString() + brandList[i].BrandID.ToString();
StoreBrandBL storeBrandBL = new StoreBrandBL();
CheckBox chkBrand = (CheckBox)contentPlaceHolder.FindControl(brandName);
if (chkBrand != null) {
if (chkBrand.Checked) {
StoreBrandDO storeBrandDO = new StoreBrandDO();
storeBrandDO.StoreID = storeID;
storeBrandDO.BrandID = brandList[i].BrandID;
storeBrandDO.IsActive = true;
storeBrandBL.InsertStoreBrand(storeBrandDO);
}
}
}
Duplicating rows in your database should be avoided in the code and protected against in the database.
As hwcverwe said you can use table constraints but you should also try to set the primary key correctly for each table.
If you are using surrogate keys on all tables (such as the StoreID and BrandID I see in your code) then you will have to use unique table constraints to prevent duplicate data. Configuring your database correctly will also show up the problem areas in your code as the database will throw an exception when an insert fails.
EDIT: In response to your comment your question title is incorrect if you are asking about CheckBox controls.
Looking at the code it appears you are trying to find a checkbox control in a ContentPlaceholder but you do not show the code which creates the checkboxes.

Convert DataTable to LINQ: Unable to query multiple fields

Importing a spreadsheet I have filled a DataTable object with that data and returns expected results.
Attempting to put this into a format I can easily query to search for problem records I have done the following
public void Something(DataTable dt)
{
var data = from row in dt.AsEnumerable()
select row["Order"].ToString();
}
Works as expected giving me a list of orders. However I cannot add other fields to this EnumerableRowCollection. Attempting to add other fields as follows gives me an error
public void Something(DataTable dt)
{
// row["Version"] throws an error on me
var data = from row in dt.AsEnumerable()
select row["Order"].ToString(), row["Version"].ToString();
}
Error: "A local variable named 'row' cannot be declared in this scope because it would give a different meaning to 'row' which is already used in a 'child' scope to donate something else"
I'm thinking I need to alias the column name but I'm having no luck. What am I missing here?
It sounds like you're writing a bad select statement. Try the following:
public void Something(DataTable dt)
{
var data = from row in dt.AsEnumerable()
select new {
Order = row["Order"].ToString(),
Something = row["Something"].ToString(),
Customer = row["Customer"].ToString(),
Address = row["Address"].ToString()
};
}
That will create a new collection of Anonymously Typed objects that you can iterate over and use as needed. Keep in mind, though, that you want be able to return data from the function. If you need that functionality, you need to create a concrete type to use (in place of anonymous types).
I think you should use select new like this query for example:
var q = from o in db.Orders
where o.Products.ProductName.StartsWith("Asset") &&
o.PaymentApproved == true
select new { name = o.Contacts.FirstName + " " +
o.Contacts.LastName,
product = o.Products.ProductName,
version = o.Products.Version +
(o.Products.SubVersion * 0.1)
};
You probably want the following.
var data = from row
in dt.AsEnumerable()
select new { Order = row["Order"].ToString(), Version = row["Version"].ToString() };

Categories

Resources