Related
I'm using fuzzyString to buy names from my list. I have a class Customer in which I want to compare a name with all other existing names.
My Customer class:
public class Customer
{
public string Name { get; set; }
public string Phone { get; set; }
public string Email { get; set; }
public string Contact { get; set; }
public int ID { get; set; }
public int NIF { get; set; }
public string NewName { get; set; }
public string PostalCode { get; set; }
public string City { get; set; }
}
In this code, I get the data from an Excel sheet and put it in the list. Now I want to compare the names:
static void Main(string[] args)
{
var customer = ReadXls();
foreach (var item in customer)
{
// Console.WriteLine($"Name:{item.Name}\n Phone:{item.Phone}\nContact:{item.Contact}\nEmail:{item.Email}\n");
List<FuzzyStringComparisonOptions> options = new List<FuzzyStringComparisonOptions>();
// Choose which algorithms should weigh in for the comparison
options.Add(FuzzyStringComparisonOptions.UseOverlapCoefficient);
options.Add(FuzzyStringComparisonOptions.UseLongestCommonSubsequence);
options.Add(FuzzyStringComparisonOptions.UseLongestCommonSubstring);
// Choose the relative strength of the comparison - is it almost exactly equal? or is it just close?
FuzzyStringComparisonTolerance tolerance = FuzzyStringComparisonTolerance.Normal;
bool result = item.Name.ApproximatelyEquals(item.Name, options, tolerance);
// Get a boolean determination of approximate equality
// double simLevenshtein = 1 - source.sor(target);
double hamming = item.Name.HammingDistance(item.Name);
double jaccard = item.Name.JaccardDistance(item.Name);
double jaro = item.Name.JaroDistance(item.Name);
double lev = item.Name.LevenshteinDistance(item.Name);
Console.WriteLine(result + " " + hamming + " " + jaccard + " " + jaro+" " + lev);
if (result == true)
{
Console.WriteLine(item.Name);
}
Console.WriteLine($"Name:{item.Name}\n Phone:{item.Phone}\nContact:{item.Contact}\nEmail:{item.Email}\n");
}
}
private static List<Customer> ReadXls()
{
var response = new List<Customer>();
string FileName;
Console.WriteLine("Diretório do ficheiro:");
FileName = Console.ReadLine();
FileInfo existingFile = new FileInfo(FileName);
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
using (ExcelPackage package = new ExcelPackage(existingFile))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets[0];
int colCount = worksheet.Dimension.End.Column;
int rowCount = worksheet.Dimension.End.Row;
int row = 2;
int col = 1;
while (string.IsNullOrWhiteSpace(worksheet.Cells[row, col].Value?.ToString()) == false)
{
Customer customer = new Customer();
customer.Name = worksheet.Cells[row, 4].Text.Trim().ToUpper();
customer.Phone = worksheet.Cells[row, 5].Text.Trim();
// customer.Phone = Regex.Replace(customer.Phone, "\\+[0-9] {1,}", "");
customer.Phone = Regex.Replace(customer.Phone, #"\s", "");
customer.Phone = customer.Phone.Replace("+351", "");
customer.Phone = customer.Phone.Replace("+44", "");
customer.Phone = customer.Phone.Replace("+34", "");
customer.Phone = customer.Phone.Replace("+244", "");
customer.Phone = customer.Phone.Replace("+33", "");
customer.Phone = customer.Phone.Replace("+49", "");
customer.Contact = worksheet.Cells[row, 7].Text.Trim().ToLower();
customer.Contact = UppercaseWords(customer.Contact);
customer.Email = worksheet.Cells[row, 8].Text.Trim().ToLower();
response.Add(customer);
row += 1;
}
}
return response;
}
With this code it only compares the Customer.Name with the same Customer.Name.. ex:
1 compares with 1 |
2 compares with 2 |
3 compares with 3 |
But I need that:
1 compares with 2 and 3 |
2 compares with 1 and 3 |
3 compares with 1 and 2 |
I have a SQlite based Xamarin Forms application on my Android Phone and Wear device. Syncing between my Phone and my Wear watch is performed according to my answer to another Question.
My database has the folowing tables Match and MatchStat:
public class Match
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public DateTime MatchDate { get; set; }
public TimeSpan MatchTime { get; set; }
public string Home { get; set; }
public string Guest { get; set; }
public int HomeScore { get; set; }
public int GuestScore { get; set; }
public bool Active { get; set; }
public bool Done { get; set; }
public string HomeColor { get; set; }
public string GuestColor { get; set; }
public Match()
{ }
}
public class MatchStat
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public int MatchId { get; set; }
public int ActionMin { get; set; }
public int HomeScore { get; set; }
public int GuestScore { get; set; }
public string ActionItem { get; set; }
public string PlayerName { get; set; }
public MatchStat()
{ }
}
If I want to sync my Match and all the MatchStat data from one device to the other I am doing it by mapping the data as strings in my MainActivity:
public async static void SendNewMatch(Match match, string path)
{
if (!client.IsConnected)
client.Connect();
await Task.Delay(200);
try
{
var request = PutDataMapRequest.Create(path);
var map = request.DataMap;
if (match != null)
{
map.PutString("Device", device);
map.PutString("Item", "AddMatch");
map.PutString("Home", match.Home);
map.PutString("Guest", match.Guest);
map.PutString("Active", match.Active.ToString());
map.PutString("Done", match.Done.ToString());
map.PutString("GuestScore", match.GuestScore.ToString());
map.PutString("HomeScore", match.HomeScore.ToString());
map.PutString("Date", match.MatchDate.Date.ToString());
map.PutString("Time", match.MatchTime.ToString());
map.PutLong("UpdatedAt", DateTime.UtcNow.Ticks);
await WearableClass.DataApi.PutDataItem(client, request.AsPutDataRequest());
}
request.UnregisterFromRuntime();
}
catch
{ }
finally
{
client.Disconnect();
}
}
public async static void SendMatchStat(MatchStat matchstat, Match match, int matchstatsize, string path)
{
if (!client.IsConnected)
client.Connect();
await Task.Delay(200);
try
{
var request = PutDataMapRequest.Create(path);
var map = request.DataMap;
MatchHelper mh = new MatchHelper();
if (matchstat != null)
{
map.PutString("Device", device);
map.PutString("Item", "MatchStat");
map.PutString("Home", match.Home);
map.PutString("Date", match.MatchDate.Date.ToString());
map.PutString("Time", match.MatchTime.ToString());
map.PutString("ActionItem", matchstat.ActionItem);
map.PutString("ActionMin", matchstat.ActionMin.ToString());
map.PutString("GuestScore", matchstat.GuestScore.ToString());
map.PutString("HomeScore", matchstat.HomeScore.ToString());
map.PutString("MatchStatSize", matchstatsize.ToString());
//map.PutString("PlayerName", matchstat.PlayerName.ToString());
map.PutLong("UpdatedAt", DateTime.UtcNow.Ticks);
await WearableClass.DataApi.PutDataItem(client, request.AsPutDataRequest());
}
request.UnregisterFromRuntime();
}
catch
{ }
finally
{
client.Disconnect();
}
}
public void ProcessMessage(Intent intent)
{
if (intent.GetStringExtra("Device") != device)
{
switch (intent.GetStringExtra("Item"))
{
case "AddMatch":
{
AddMatch(intent);
break;
}
case "MatchStat":
{
InsertMatchStat(intent);
break;
}
}
}
}
private void AddMatch(Intent intent)
{
MatchHelper mh = new MatchHelper();
if (bool.Parse(intent.GetStringExtra("Active")))
{
ObservableCollection<Match> activeMatches = mh.GetActiveMatches();
foreach (Match activeMatch in activeMatches)
{
mh.InactivateMatch(activeMatch);
}
}
Match newmatch = new Match();
newmatch.Home = intent.GetStringExtra("Home");
newmatch.Guest = intent.GetStringExtra("Guest");
newmatch.HomeColor = intent.GetStringExtra("HomeColor");
newmatch.GuestColor = intent.GetStringExtra("GuestColor");
newmatch.Active = bool.Parse(intent.GetStringExtra("Active"));
newmatch.Done = bool.Parse(intent.GetStringExtra("Done"));
newmatch.HomeScore = int.Parse(intent.GetStringExtra("HomeScore"));
newmatch.GuestScore = int.Parse(intent.GetStringExtra("GuestScore"));
newmatch.Active = bool.Parse(intent.GetStringExtra("Active"));
newmatch.Done = bool.Parse(intent.GetStringExtra("Done"));
newmatch.MatchDate = DateTime.Parse(intent.GetStringExtra("Date"));
newmatch.MatchTime = TimeSpan.Parse(intent.GetStringExtra("Time"));
mh.InsertMatch(newmatch);
}
private void InsertMatchStat(Intent intent)
{
MatchHelper mh = new MatchHelper();
Match match = mh.GetSpecificMatch(intent.GetStringExtra("Home"), DateTime.Parse(intent.GetStringExtra("Date")), TimeSpan.Parse(intent.GetStringExtra("Time")));
if (match != null)
{
MatchStat machstat = new MatchStat();
machstat.MatchId = match.Id;
machstat.ActionItem = intent.GetStringExtra("ActionItem");
machstat.ActionMin = int.Parse(intent.GetStringExtra("ActionMin"));
machstat.GuestScore = int.Parse(intent.GetStringExtra("GuestScore"));
machstat.HomeScore = int.Parse(intent.GetStringExtra("HomeScore"));
machstat.PlayerName = intent.GetStringExtra("PlayerName");
mh.InsertMatchStat(machstat);
}
}
In my WearService I have my OnDataChanged:
public override void OnDataChanged(DataEventBuffer dataEvents)
{
var dataEvent = Enumerable.Range(0, dataEvents.Count)
.Select(i => dataEvents.Get(i).JavaCast<IDataEvent>())
.FirstOrDefault(x => x.Type == DataEvent.TypeChanged && x.DataItem.Uri.Path.Equals(_syncPath));
if (dataEvent == null)
return;
//get data from wearable
var dataMapItem = DataMapItem.FromDataItem(dataEvent.DataItem);
var map = dataMapItem.DataMap;
Intent intent = new Intent();
intent.SetAction(Intent.ActionSend);
intent.PutExtra("Device", map.GetString("Device"));
intent.PutExtra("Item", map.GetString("Item"));
switch (map.GetString("Item"))
{
case "AddMatch":
{
intent.PutExtra("Home", map.GetString("Home"));
intent.PutExtra("Guest", map.GetString("Guest"));
intent.PutExtra("HomeColor", map.GetString("HomeColor"));
intent.PutExtra("GuestColor", map.GetString("GuestColor"));
intent.PutExtra("Active", map.GetString("Active"));
intent.PutExtra("Done", map.GetString("Done"));
intent.PutExtra("HomeScore", map.GetString("HomeScore"));
intent.PutExtra("GuestScore", map.GetString("GuestScore"));
intent.PutExtra("Date", map.GetString("Date"));
intent.PutExtra("Time", map.GetString("Time"));
LocalBroadcastManager.GetInstance(this).SendBroadcast(intent);
break;
}
case "MatchStat":
{
intent.PutExtra("Home", map.GetString("Home"));
intent.PutExtra("Date", map.GetString("Date"));
intent.PutExtra("Time", map.GetString("Time"));
intent.PutExtra("ActionItem", map.GetString("ActionItem"));
intent.PutExtra("ActionMin", map.GetString("ActionMin"));
intent.PutExtra("GuestScore", map.GetString("GuestScore"));
intent.PutExtra("HomeScore", map.GetString("HomeScore"));
intent.PutExtra("PlayerName", map.GetString("PlayerName"));
LocalBroadcastManager.GetInstance(this).SendBroadcast(intent);
break;
}
}
}
Instead of sending the data via separate strings I want to send my Match data as database file (if necessary as .ToString). Is it possible to achieve this and how can I thereafter retrieve the data.
Second of all I have my MatchStats as a list (IEnumerable or ObservableCollection). Is it possible to send this as a list or do I have to send each MatchStat seperately. By sending the Matchstats seperately my other device will not receive them in the desired order and not all MatchStats are received.
Instead of sending database data as database file I now solved this by sending the Matchstats in one file instead of sending all seperate data.
public async static void SendMatchStats(ObservableCollection<MatchStat> matchstats, Match match, int matchstatsize, string path)
{
if (!client.IsConnected)
client.Connect();
await Task.Delay(80);
try
{
var request = PutDataMapRequest.Create(path);
var map = request.DataMap;
MatchHelper mh = new MatchHelper();
int cnt = 1;
if (matchstatsize != 0)
{
map.PutString("Device", device);
map.PutString("Item", "MatchStats");
map.PutString("Home", match.Home);
map.PutString("Date", match.MatchDate.Date.ToString());
map.PutString("Time", match.MatchTime.ToString());
map.PutString("MatchStatSize", matchstatsize.ToString());
map.PutString("Path", path);
foreach (MatchStat matchstat in matchstats)
{
map.PutString("ActionItem" + cnt.ToString(), matchstat.ActionItem);
map.PutString("ActionMin" + cnt.ToString(), matchstat.ActionMin.ToString());
map.PutString("Color" + cnt.ToString(), matchstat.Color);
//map.PutString("ColorSchemeId", matchstat.ColorSchemeId.ToString());
map.PutString("GuestScore" + cnt.ToString(), matchstat.GuestScore.ToString());
map.PutString("HomeScore" + cnt.ToString(), matchstat.HomeScore.ToString());
if (matchstat.PlayerName == null)
map.PutString("PlayerName" + cnt.ToString(), "");
else
map.PutString("PlayerName" + cnt.ToString(), matchstat.PlayerName.ToString());
cnt++;
}
map.PutLong("UpdatedAt", DateTime.UtcNow.Ticks);
await WearableClass.DataApi.PutDataItem(client, request.AsPutDataRequest());
}
request.SetUrgent();
request.UnregisterFromRuntime();
}
catch
{ }
finally
{
client.Disconnect();
}
}
In my WearService I have my OnDataChanged:
case "MatchStats":
{
int size = int.Parse(map.GetString("MatchStatSize"));
intent.PutExtra("Home", map.GetString("Home"));
intent.PutExtra("Date", map.GetString("Date"));
intent.PutExtra("Time", map.GetString("Time"));
intent.PutExtra("MatchStatSize", map.GetString("MatchStatSize"));
intent.PutExtra("Path", map.GetString("Path"));
for (int cnt = 1; cnt <= size; cnt++)
{
intent.PutExtra("ActionItem" + cnt.ToString(), map.GetString("ActionItem" + cnt.ToString()));
intent.PutExtra("ActionMin" + cnt.ToString(), map.GetString("ActionMin" + cnt.ToString()));
intent.PutExtra("Color" + cnt.ToString(), map.GetString("Color" + cnt.ToString()));
intent.PutExtra("GuestScore" + cnt.ToString(), map.GetString("GuestScore" + cnt.ToString()));
intent.PutExtra("HomeScore" + cnt.ToString(), map.GetString("HomeScore" + cnt.ToString()));
intent.PutExtra("PlayerName" + cnt.ToString(), map.GetString("PlayerName" + cnt.ToString()));
Console.WriteLine("PutExtra " + map.GetString("ActionMin" + cnt.ToString()) + " min " + map.GetString("HomeScore" + cnt.ToString()) + "-" + map.GetString("GuestScore" + cnt.ToString()));
Console.WriteLine("GetStringExtra " + intent.GetStringExtra("ActionMin" + cnt.ToString()) + " min " + intent.GetStringExtra("HomeScore" + cnt.ToString()) + "-" + intent.GetStringExtra("GuestScore" + cnt.ToString()));
}
LocalBroadcastManager.GetInstance(this).SendBroadcast(intent);
break;
}
And in MainActivity I am processing the data in a seperate void InsertMatchstats:
private void InsertMatchStats(Intent intent)
{
MatchHelper mh = new MatchHelper();
Match match = mh.GetSpecificMatch(intent.GetStringExtra("Home"), DateTime.Parse(intent.GetStringExtra("Date")), TimeSpan.Parse(intent.GetStringExtra("Time")));
int size = int.Parse(intent.GetStringExtra("MatchStatSize"));
if (match != null)
{
for (int cnt = 1; cnt <= size; cnt++)
{
MatchStat matchstat = new MatchStat
{
MatchId = match.Id,
ActionItem = intent.GetStringExtra("ActionItem" + cnt.ToString()),
ActionMin = int.Parse(intent.GetStringExtra("ActionMin" + cnt.ToString())),
Color = intent.GetStringExtra("Color" + cnt.ToString()),
//ColorSchemeId = int.Parse(intent.GetStringExtra("ColorSchemeId"));
GuestScore = int.Parse(intent.GetStringExtra("GuestScore" + cnt.ToString())),
HomeScore = int.Parse(intent.GetStringExtra("HomeScore" + cnt.ToString())),
PlayerName = intent.GetStringExtra("PlayerName" + cnt.ToString()),
Sync = true
};
if (matchstat.Color == null)
matchstat.Color = "#FFFFFF";
MatchStat checkMatchStat = mh.CheckMatchStat(matchstat.HomeScore, matchstat.GuestScore, matchstat.ActionItem, matchstat.MatchId);
if (checkMatchStat == null)
mh.InsertMatchStat(matchstat);
else
{
checkMatchStat.ActionMin = matchstat.ActionMin;
checkMatchStat.Color = matchstat.Color;
//checkMatchStat.ColorSchemeId = matchstat.ColorSchemeId;
checkMatchStat.PlayerName = matchstat.PlayerName;
mh.UpdateMatchStat(checkMatchStat);
}
Console.WriteLine("PutExtra " + intent.GetStringExtra("ActionMin" + cnt.ToString()) + " min " + intent.GetStringExtra("HomeScore" + cnt.ToString()) + "-" + intent.GetStringExtra("GuestScore" + cnt.ToString()));
}
SendBack(intent.GetStringExtra("Path"));
}
}
Using this method the syncing is much faster and more precise. No data is lost and all data is received and processed in the right order.
As an overview I am attempting to add Export() functionality to my application -- allowing the user to specify certain model fields and only export the values in those fields by querying with LINQ and using the EPPlus library to Export. I am attempting to implement Dynamic LINQ functionality in my MVC5/EF Code-First application based on THIS example, but not having much luck so far.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using InventoryTracker.DAL;
using OfficeOpenXml;
using InventoryTracker.Models;
using System.Linq.Dynamic;
namespace InventoryTracker.Controllers
{
public class ExportController : Controller
{
InventoryTrackerContext _db = new InventoryTrackerContext();
public static List<DynamicColumns> DynamicColumnsCollection = new List<DynamicColumns>();
[HttpPost]
public ActionResult ExportUsingEPPlus(ExportAssetsViewModel model)
{
//FileInfo newExcelFile = new FileInfo(output);
ExcelPackage package = new ExcelPackage();
var ws = package.Workbook.Worksheets.Add("TestExport");
var exportFields = new List<string>();
foreach(var selectedField in model.SelectedFields)
{
// Adds selected fields to [exportFields] List<string>
exportFields.Add(model.ListOfExportFields.First(s => s.Key == selectedField).Value);
}
//int cnt = 0;
//foreach(var column in exportFields)
for (int cnt = 0; cnt < 10; cnt++ )
{
DynamicColumnsCollection.Add(new DynamicColumns()
{
Id = cnt,
ip_address = "ip_address" + cnt,
mac_address = "mac_address" + cnt,
note = "note" + cnt,
owner = "owner" + cnt,
cost = "cost" + cnt,
po_number = "po_number" + cnt,
description = "description" + cnt,
invoice_number = "invoice_number" + cnt,
serial_number = "serial_number" + cnt,
asset_tag_number = "asset_tag_number" + cnt,
acquired_date = "acquired_date" + cnt,
disposed_date = "disposed_date" + cnt,
verified_date = "verified_date" + cnt,
created_date = "created_date" + cnt,
created_by = "created_by" + cnt,
modified_date = "modified_date" + cnt,
modified_by = "modified_by" + cnt
});
}
//var selectStatement = DynamicSelectionColumns(exportFields);
IQueryable collection = DynamicSelectionColumns(new List<string>() {
"id",
"owner",
"note"
});
// Loops to insert column headings into Row 1 of Excel
for (int i = 0; i < exportFields.Count(); i++ )
{
ws.Cells[1, i + 1].Value = exportFields[i].ToString();
}
// Process data from [collectin] into Excel???
ws.Cells["A2"].LoadFromCollection(collection.ToString());
// ws.Cells["A2"].LoadFromCollection(selectStatement.ToString());
var memoryStream = new MemoryStream();
package.SaveAs(memoryStream);
string fileName = "Exported-InventoryAssets-" + DateTime.Now + ".xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
memoryStream.Position = 0;
return File(memoryStream, contentType, fileName);
}
public IQueryable DynamicSelectionColumns(List<string> fieldsForExport)
{
using (var db = new InventoryTrackerContext())
{
string fieldIds = "," + "4,5,3,2,6,17,11,12" + ",";
//var taskColum = Enum.GetValues(typeof(EnumTasks)).Cast<EnumTasks>().Where(e => fieldIds.Contains("," + ((int)e).ToString() + ",")).Select(e => e.ToString().Replace("_", ""));
var taskColum = Enum.GetValues(typeof(EnumTasks)).Cast<EnumTasks>().Where(e => fieldIds.Contains("," + ((int)e).ToString() + ",")).Select(e => e.ToString());
////string select = "new ( TaskId, " + (taskColum.Count() > 0 ? string.Join(", ", taskColum) + ", " : "") + "Id )";
//string select = "new ( " + string.Join(", ", fieldsForExport) + ")";
////return db.INV_Assets.ToList().Select(t => new DynamicColumns() { Id = t.Id, TaskId = Project != null ? Project.Alias + "-" + t.Id : t.Id.ToString(),
if (!fieldsForExport.Any())
{
return null;
}
string select = string.Format("new ( {0} )", string.Join(", ", fieldsForExport.ToArray()));
var collection = DynamicColumnsCollection.Select(t => new DynamicColumns()
{
Id = t.Id,
//Manufacturer = Convert.ToString(t.Manufacturer.manufacturer_description),
//Type = t.Type.type_description,
//Location = t.Location.location_room,
//Vendor = t.Vendor.vendor_name,
//Status = t.Status.status_description,
ip_address = t.ip_address,
mac_address = t.mac_address,
note = t.note,
owner = t.owner,
cost = t.cost,
po_number = t.po_number,
description = t.description,
invoice_number = t.invoice_number,
serial_number = t.serial_number,
asset_tag_number = t.asset_tag_number,
acquired_date = t.acquired_date,
disposed_date = t.disposed_date,
verified_date = t.verified_date,
created_date = t.created_date,
created_by = t.created_by,
modified_date = t.modified_date,
modified_by = t.modified_by
}).ToList().AsQueryable().Select(select);
return collection;
}
}
}
public class DynamicColumns : INV_Assets
{
public string Model { get; set; }
public string Manufacturer { get; set; }
public string Type { get; set; }
public string Location { get; set; }
public string Vendor { get; set; }
public string Status { get; set; }
public string ip_address { get; set; }
public string mac_address { get; set; }
public string note { get; set; }
public string owner { get; set; }
public string cost { get; set; }
public string po_number { get; set; }
public string description { get; set; }
public string invoice_number { get; set; }
public string serial_number { get; set; }
public string asset_tag_number { get; set; }
public string acquired_date { get; set; }
public string disposed_date { get; set; }
public string verified_date { get; set; }
public string created_date { get; set; }
public string created_by { get; set; }
public string modified_date { get; set; }
public string modified_by { get; set; }
}
public enum EnumTasks
{
Model = 1,
Manufacturer = 2,
Type = 3,
Location = 4,
Vendor = 5,
Status = 6,
ip_address = 7,
mac_address = 8,
note = 9,
owner = 10,
cost = 11,
po_number = 12,
description = 13,
invoice_number = 14,
serial_number = 15,
asset_tag_number = 16,
acquired_date = 17,
disposed_date = 18,
verified_date = 19,
created_date = 20,
created_by = 21,
modified_date = 22,
modified_by = 23
}
//https://stackoverflow.com/questions/5796151/export-model-data-to-excel-mvc
//https://landokal.wordpress.com/2011/04/28/asp-net-mvc-export-to-excel-trick/
}
My code is exporting my selected columns values from my MultiSelectList on my View into Row 1 of the Excel spreadsheet, but I have something amiss with my dynamic linq querying as the data that gets output is simply the value 0 in A2:A180 no matter how many fields I specify for output.
Can anyone with more experience or who has used System.Linq.Dynamic weigh in on this?
Here is something that I am using for some time:
public class ExcelExportHelper
{
public static string ExcelContentType { get { return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; } }
public static DataTable ToDataTable<T>(List<T> data)
{
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T));
DataTable table = new DataTable();
for (int i = 0; i < props.Count; i++)
{
PropertyDescriptor prop = props[i];
//table.Columns.Add(prop.Name, prop.PropertyType);
table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType); // to avoid nullable types
}
object[] values = new object[props.Count];
foreach (T item in data)
{
for (int i = 0; i < values.Length; i++)
{
values[i] = props[i].GetValue(item);
}
table.Rows.Add(values);
}
return table;
}
public static byte[] ExportExcel(DataTable dt, string Heading = "", params string[] IgnoredColumns)
{
byte[] result = null;
using (ExcelPackage pck = new ExcelPackage())
{
ExcelWorksheet ws = pck.Workbook.Worksheets.Add("Exported Data");
int StartFromRow = String.IsNullOrEmpty(Heading) ? 1: 3;
// add the content into the Excel file
ws.Cells["A" + StartFromRow].LoadFromDataTable(dt, true);
// autofit width of cells with small content
int colindex = 1;
foreach (DataColumn col in dt.Columns)
{
ExcelRange columnCells = ws.Cells[ws.Dimension.Start.Row, colindex, ws.Dimension.End.Row, colindex];
int maxLength = columnCells.Max(cell => cell.Value.ToString().Count());
if (maxLength < 150)
ws.Column(colindex).AutoFit();
colindex++;
}
// format header - bold, yellow on black
using (ExcelRange r = ws.Cells[StartFromRow, 1, StartFromRow, dt.Columns.Count])
{
r.Style.Font.Color.SetColor(System.Drawing.Color.Yellow);
r.Style.Font.Bold = true;
r.Style.Fill.PatternType = OfficeOpenXml.Style.ExcelFillStyle.Solid;
r.Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.Black);
}
// format cells - add borders
using (ExcelRange r = ws.Cells[StartFromRow + 1, 1, StartFromRow + dt.Rows.Count, dt.Columns.Count])
{
r.Style.Border.Top.Style = ExcelBorderStyle.Thin;
r.Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
r.Style.Border.Left.Style = ExcelBorderStyle.Thin;
r.Style.Border.Right.Style = ExcelBorderStyle.Thin;
r.Style.Border.Top.Color.SetColor(System.Drawing.Color.Black);
r.Style.Border.Bottom.Color.SetColor(System.Drawing.Color.Black);
r.Style.Border.Left.Color.SetColor(System.Drawing.Color.Black);
r.Style.Border.Right.Color.SetColor(System.Drawing.Color.Black);
}
// removed ignored columns
for (int i = dt.Columns.Count - 1; i >= 0; i--)
{
if (IgnoredColumns.Contains(dt.Columns[i].ColumnName))
{
ws.DeleteColumn(i + 1);
}
}
// add header and an additional column (left) and row (top)
if (!String.IsNullOrEmpty(Heading))
{
ws.Cells["A1"].Value = Heading;
ws.Cells["A1"].Style.Font.Size = 20;
ws.InsertColumn(1, 1);
ws.InsertRow(1, 1);
ws.Column(1).Width = 5;
}
result = pck.GetAsByteArray();
}
return result;
}
public static byte[] ExportExcel<T>(List<T> data, string Heading = "", params string[] IgnoredColumns)
{
return ExportExcel(ToDataTable<T>(data), Heading, IgnoredColumns);
}
}
With these you can export a list of objects or a datatable to an Excel file. Additionally, you can specify a header and columns/properties to be ignored (like ID). Also, there are some formatting added and also small cells will auto fit in width.
Using this code you can use this in your controller action that is expecting a FileResult:
byte[] filecontent = ExcelExportHelper.ExportExcel(...);
return File(filecontent, ExcelExportHelper.ExcelContentType, "FileName.xlsx");
I hope this helps!
As an overview I am attempting to add Export() functionality to my application -- allowing the user to specify certain model fields and only export the values in those fields by querying with LINQ and using the EPPlus library to Export. I am attempting to implement Dynamic LINQ functionality in my MVC5/EF Code-First application based on THIS example, but seem to be missing some things to get it working or not understanding something.
First I added a new class file to my main project folder called DynamicLibrary.cs. When I download the .zip HERE, I "believe" the code I wanted was the Dynamic.cs file code which I copied into DynamicLibrary.cs in my project. Doing this allowed me to reference using System.Linq.Dynamic in my project.
Now I'm stuck trying to figure out how to setup the rest for Dynamic LINQ.
In my ExportController within the namespace InventoryTracker.Controllers {} but outside the public class ExportController : Controller { } I added the example code based upon the fields in my INV_Assets model I am attempting to Export:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using InventoryTracker.DAL;
using OfficeOpenXml;
using InventoryTracker.Models;
using System.Linq.Dynamic;
namespace InventoryTracker.Controllers
{
public class ExportController : Controller
{
InventoryTrackerContext _db = new InventoryTrackerContext();
// GET: Export
public ActionResult Index()
{
ExportAssetsViewModel expViewMod = new ExportAssetsViewModel();
return View(expViewMod);
}
public ActionResult Export()
{
GridView gv = new GridView();
gv.DataSource = _db.INV_Assets.ToList();
gv.DataBind();
Response.ClearContent();
Response.Buffer = true;
Response.AddHeader("content-disposition", "attachment; filename=InventoryAssets-" + DateTime.Now + ".xls");
Response.ContentType = "application/ms-excel";
Response.Charset = "";
StringWriter sw = new StringWriter();
HtmlTextWriter htw = new HtmlTextWriter(sw);
gv.RenderControl(htw);
Response.Output.Write(sw.ToString());
Response.Flush();
Response.End();
return RedirectToAction("StudentDetails");
}
[HttpPost]
public ActionResult ExportUsingEPPlus(ExportAssetsViewModel model)
{
//FileInfo newExcelFile = new FileInfo(output);
ExcelPackage package = new ExcelPackage();
var ws = package.Workbook.Worksheets.Add("TestExport");
var exportFields = new List<string>();
foreach(var selectedField in model.SelectedFields)
{
// Adds selected fields to [exportFields] List<string>
exportFields.Add(model.ListOfExportFields.First(s => s.Key == selectedField).Value);
}
// Loops to insert column headings into Row 1 of Excel
for (int i = 0; i < exportFields.Count(); i++ )
{
ws.Cells[1, i + 1].Value = exportFields[i].ToString();
}
// INVALID - Need to query table INV_Assets for all values of selected fields and insert into appropriate columns.
if (exportFields.Count() > 0)
{
var exportAssets = from ia in _db.INV_Assets
select new {
ia.ip_address,
}
ws.Cells["A2"].LoadFromCollection(exportFields);
}
var memoryStream = new MemoryStream();
package.SaveAs(memoryStream);
string fileName = "Exported-InventoryAssets-" + DateTime.Now + ".xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
memoryStream.Position = 0;
return File(memoryStream, contentType, fileName);
}
}
public class DynamicColumns : INV_Assets
{
//public int Id { get; set; }
//public int Model_Id { get; set; }
public virtual INV_Models Model { get; set; }
//public int Manufacturer_Id { get; set; }
public virtual INV_Manufacturers Manufacturer { get; set; }
//public int Type_Id { get; set; }
public virtual INV_Types Type { get; set; }
//public int Location_Id { get; set; }
public virtual INV_Locations Location { get; set; }
//public int Vendor_Id { get; set; }
public virtual INV_Vendors Vendor { get; set; }
//public int Status_Id { get; set; }
public virtual INV_Statuses Status { get; set; }
public string ip_address { get; set; }
public string mac_address { get; set; }
public string note { get; set; }
public string owner { get; set; }
public decimal cost { get; set; }
public string po_number { get; set; }
public string description { get; set; }
public int invoice_number { get; set; }
public string serial_number { get; set; }
public string asset_tag_number { get; set; }
public DateTime? acquired_date { get; set; }
public DateTime? disposed_date { get; set; }
public DateTime? verified_date { get; set; }
public DateTime created_date { get; set; }
public string created_by { get; set; }
public DateTime? modified_date { get; set; }
public string modified_by { get; set; }
}
public enum EnumTasks
{
Model = 1,
Manufacturer = 2,
Type = 3,
Location = 4,
Vendor = 5,
Status = 6,
ip_address = 7,
mac_address = 8,
note = 9,
owner = 10,
cost = 11,
po_number = 12,
description = 13,
invoice_number = 14,
serial_number = 15,
asset_tag_number = 16,
acquired_date = 17,
disposed_date = 18,
verified_date = 19,
created_date = 20,
created_by = 21,
modified_date = 22,
modified_by = 23
}
public IQueryable DynamicSelectionColumns()
{
using (var db = new TrackerDataContext())
{
string fieldIds = "," + "4,5,3,2,6,17,11,12" + ",";
var taskColum = Enum.GetValues(typeof(EnumTasks)).Cast<EnumTasks>().Where(e => fieldIds.Contains("," + ((int)e).ToString() + ",")).Select(e => e.ToString().Replace("_", ""));
string select = "new ( TaskId, " + (taskColum.Count() > 0 ? string.Join(", ", taskColum) + ", " : "") + "Id )";
return db.Task.ToList().Select(t => new DynamicColumns() { Id = t.Id, TaskId = Project != null ? Project.Alias + "-" + t.Id : t.Id.ToString(), ActualTime = t.ActualTime, AssignedBy = t.AssignedBy.ToString(), AssignedDate = t.AssignedDate, AssignedTo = t.AssignedTo.ToString(), CreatedDate = t.CreatedDate, Details = t.Details, EstimatedTime = t.EstimatedTime, FileName = t.FileName, LogWork = t.LogWork, Module = t.Module != null ? t.Module.Name : "", Priority = t.Priority != null ? t.Priority.Name : "", Project = t.Project != null ? t.Project.Name : "", ResolveDate = t.ResolveDate, Status = t.Status != null ? t.Status.Name : "", Subject = t.Subject, TaskType = t.TaskType != null ? t.TaskType.Type : "", Version = t.Version != null ? t.Version.Name : "" }).ToList().AsQueryable().Select(select);
}
}
}
I am not 100% sure this is set up in the right location. The last method below has 5 errors:
IQueryable - Expected class, delegate, enum, interface, or struct.
InventoryTrackerContext - Expected class, delegate, enum, interface, or struct.
DynamicColumns() - Expected class, delegate, enum, interface, or struct.
Closing } for public IQueryable DynamicSelectionColumns() - Type or namespace definition, or end-of-file expected.
Closing } for namespace InventoryTracker.Controllers - Type or namespace definition, or end-of-file expected.
public IQueryable DynamicSelectionColumns()
{
using (var db = new InventoryTrackerContext())
{
string fieldIds = "," + "4,5,3,2,6,17,11,12" + ",";
var taskColum = Enum.GetValues(typeof(EnumTasks)).Cast<EnumTasks>().Where(e => fieldIds.Contains("," + ((int)e).ToString() + ",")).Select(e => e.ToString().Replace("_", ""));
string select = "new ( TaskId, " + (taskColum.Count() > 0 ? string.Join(", ", taskColum) + ", " : "") + "Id )";
return db.Task.ToList().Select(t => new DynamicColumns() { Id = t.Id, TaskId = Project != null ? Project.Alias + "-" + t.Id : t.Id.ToString(), ActualTime = t.ActualTime, AssignedBy = t.AssignedBy.ToString(), AssignedDate = t.AssignedDate, AssignedTo = t.AssignedTo.ToString(), CreatedDate = t.CreatedDate, Details = t.Details, EstimatedTime = t.EstimatedTime, FileName = t.FileName, LogWork = t.LogWork, Module = t.Module != null ? t.Module.Name : "", Priority = t.Priority != null ? t.Priority.Name : "", Project = t.Project != null ? t.Project.Name : "", ResolveDate = t.ResolveDate, Status = t.Status != null ? t.Status.Name : "", Subject = t.Subject, TaskType = t.TaskType != null ? t.TaskType.Type : "", Version = t.Version != null ? t.Version.Name : "" }).ToList().AsQueryable().Select(select);
}
}
Can anyone with more experience in this kind of thing weigh-in? I also checked out ScottGu's Blog, but seem to be missing or not understanding something.
EDIT:
REDACTED FOR SPACE
EDIT2:
Using the return from DynamicSelectionColumns() into my variable selectStatement, I have the following coded:
public IQueryable DynamicSelectionColumns(List<string> fieldsForExport)
{
using (var db = new InventoryTrackerContext())
{
string fieldIds = "," + "4,5,3,2,6,17,11,12" + ",";
var taskColum = Enum.GetValues(typeof(EnumTasks)).Cast<EnumTasks>().Where(e => fieldIds.Contains("," + ((int)e).ToString() + ",")).Select(e => e.ToString().Replace("_", ""));
//string select = "new ( TaskId, " + (taskColum.Count() > 0 ? string.Join(", ", taskColum) + ", " : "") + "Id )";
string select = "new ( " + string.Join(", ", fieldsForExport) + ")";
//return db.INV_Assets.ToList().Select(t => new DynamicColumns() { Id = t.Id, TaskId = Project != null ? Project.Alias + "-" + t.Id : t.Id.ToString(),
return db.INV_Assets.ToList().Select(t => new DynamicColumns() {
Id = t.Id,
Manufacturer = Convert.ToString(t.Manufacturer.manufacturer_description),
Type = t.Type.type_description,
Location = t.Location.location_room,
Vendor = t.Vendor.vendor_name,
Status = t.Status.status_description,
ip_address = t.ip_address,
mac_address = t.mac_address,
note = t.note,
owner = t.owner,
//Module = t.Module != null ? t.Module.Name : "",
cost = t.cost,
po_number = t.po_number,
description = t.description,
invoice_number = t.invoice_number,
serial_number = t.serial_number,
asset_tag_number = t.asset_tag_number,
acquired_date = t.acquired_date,
disposed_date = t.disposed_date,
verified_date = t.verified_date,
created_date = t.created_date,
created_by = t.created_by,
modified_date = t.modified_date,
modified_by = t.modified_by
}).ToList().AsQueryable().Select(select);
}
}
[HttpPost]
public ActionResult ExportUsingEPPlus(ExportAssetsViewModel model)
{
ExcelPackage package = new ExcelPackage();
var ws = package.Workbook.Worksheets.Add("TestExport");
var exportFields = new List<string>();
foreach(var selectedField in model.SelectedFields)
{
// Adds selected fields to [exportFields] List<string>
exportFields.Add(model.ListOfExportFields.First(s => s.Key == selectedField).Value);
}
var selectStatement = DynamicSelectionColumns(exportFields);
// Loops to insert column headings into Row 1 of Excel
for (int i = 0; i < exportFields.Count(); i++ )
{
ws.Cells[1, i + 1].Value = exportFields[i].ToString();
}
if (selectStatement.Count() > 0)
{
ws.Cells["A2"].LoadFromCollection(selectStatement.ToString());
}
var memoryStream = new MemoryStream();
package.SaveAs(memoryStream);
string fileName = "Exported-InventoryAssets-" + DateTime.Now + ".xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
memoryStream.Position = 0;
return File(memoryStream, contentType, fileName);
}
This yields an Excel output with columns [ip_address], [mac_address], [note], [owner], and [cost] (the fields I selected), but no data. Instead of data, I get 251 rows of 0 in column A and nothing in the others.
How do I implement the dynamic select query results into my Excel spreadsheet?
EDIT3:
Attempting ThulasiRam's suggestion (ExportController below):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using InventoryTracker.DAL;
using OfficeOpenXml;
using InventoryTracker.Models;
using System.Linq.Dynamic;
namespace InventoryTracker.Controllers
{
public class ExportController : Controller
{
InventoryTrackerContext _db = new InventoryTrackerContext();
public static List<DynamicColumns> DynamicColumnsCollection = new List<DynamicColumns>();
[HttpPost]
public ActionResult ExportUsingEPPlus(ExportAssetsViewModel model)
{
//FileInfo newExcelFile = new FileInfo(output);
ExcelPackage package = new ExcelPackage();
var ws = package.Workbook.Worksheets.Add("TestExport");
var exportFields = new List<string>();
foreach(var selectedField in model.SelectedFields)
{
// Adds selected fields to [exportFields] List<string>
exportFields.Add(model.ListOfExportFields.First(s => s.Key == selectedField).Value);
}
int cnt = 0;
foreach(var column in exportFields)
{
DynamicColumnsCollection.Add(new DynamicColumns()
{
Id = cnt,
ip_address = "ip_address" + cnt,
mac_address = "mac_address" + cnt,
note = "note" + cnt,
owner = "owner" + cnt,
cost = "cost" + cnt,
po_number = "po_number" + cnt,
description = "description" + cnt,
invoice_number = "invoice_number" + cnt,
serial_number = "serial_number" + cnt,
asset_tag_number = "asset_tag_number" + cnt,
acquired_date = "acquired_date" + cnt,
disposed_date = "disposed_date" + cnt,
verified_date = "verified_date" + cnt,
created_date = "created_date" + cnt,
created_by = "created_by" + cnt,
modified_date = "modified_date" + cnt,
modified_by = "modified_by" + cnt
});
}
//var selectStatement = DynamicSelectionColumns(exportFields);
IQueryable collection = DynamicSelectionColumns(new List<string>() {
"id",
"owner",
"note"
});
// Loops to insert column headings into Row 1 of Excel
for (int i = 0; i < exportFields.Count(); i++ )
{
ws.Cells[1, i + 1].Value = exportFields[i].ToString();
}
ws.Cells["A2"].LoadFromCollection(collection.ToString());
// ws.Cells["A2"].LoadFromCollection(selectStatement.ToString());
var memoryStream = new MemoryStream();
package.SaveAs(memoryStream);
string fileName = "Exported-InventoryAssets-" + DateTime.Now + ".xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
memoryStream.Position = 0;
return File(memoryStream, contentType, fileName);
}
public IQueryable DynamicSelectionColumns(List<string> fieldsForExport)
{
using (var db = new InventoryTrackerContext())
{
if (!fieldsForExport.Any())
{
return null;
}
string select = string.Format("new ( {0} )", string.Join(", ", fieldsForExport.ToArray()));
var collection = DynamicColumnsCollection.Select(t => new DynamicColumns()
{
Id = t.Id,
//Manufacturer = Convert.ToString(t.Manufacturer.manufacturer_description),
//Type = t.Type.type_description,
//Location = t.Location.location_room,
//Vendor = t.Vendor.vendor_name,
//Status = t.Status.status_description,
ip_address = t.ip_address,
mac_address = t.mac_address,
note = t.note,
owner = t.owner,
//Module = t.Module != null ? t.Module.Name : "",
cost = t.cost,
po_number = t.po_number,
description = t.description,
invoice_number = t.invoice_number,
serial_number = t.serial_number,
asset_tag_number = t.asset_tag_number,
acquired_date = t.acquired_date,
disposed_date = t.disposed_date,
verified_date = t.verified_date,
created_date = t.created_date,
created_by = t.created_by,
modified_date = t.modified_date,
modified_by = t.modified_by
}).ToList().AsQueryable().Select(select);
return collection;
}
}
public class DynamicColumns : INV_Assets
{
public string Model { get; set; }
public string Manufacturer { get; set; }
public string Type { get; set; }
public string Location { get; set; }
public string Vendor { get; set; }
public string Status { get; set; }
public string ip_address { get; set; }
public string mac_address { get; set; }
public string note { get; set; }
public string owner { get; set; }
public string cost { get; set; }
public string po_number { get; set; }
public string description { get; set; }
public string invoice_number { get; set; }
public string serial_number { get; set; }
public string asset_tag_number { get; set; }
public string acquired_date { get; set; }
public string disposed_date { get; set; }
public string verified_date { get; set; }
public string created_date { get; set; }
public string created_by { get; set; }
public string modified_date { get; set; }
public string modified_by { get; set; }
}
public enum EnumTasks
{
Model = 1,
Manufacturer = 2,
Type = 3,
Location = 4,
Vendor = 5,
Status = 6,
ip_address = 7,
mac_address = 8,
note = 9,
owner = 10,
cost = 11,
po_number = 12,
description = 13,
invoice_number = 14,
serial_number = 15,
asset_tag_number = 16,
acquired_date = 17,
disposed_date = 18,
verified_date = 19,
created_date = 20,
created_by = 21,
modified_date = 22,
modified_by = 23
}
What I can't figure out is where to put this relevant piece of code from their suggestion (or set it up) within my MVC application:
static void Main(string[] args)
{
IQueryable collection = DynamicSelectionColumns(new List<string>() { "id", "name" });
Console.ReadLine();
}
Any thoughts? I'm not sure how to structure the static Program() or Main() used in the example for my MVC app. In my code listed above (should I select just the note/owner field), I receive an output Excel sheet with "note" in A1, "owner" in B1, and then just the number 0 in cells A2:A180...?
The errors you're getting has nothing to do with linq or the other libraries you imported into your project.
You're declaring the function DynamicSelectionColumns in the namespace, not in the ExportController class.
After your Edit:
if your exportFields is already a list of Task columns, you can simply pass that list to DynamicSelectionColumns and have this inside:
string select = "new ( " + string.Join(", ", exportFields) + ")";
After Edit2:
Replace
ws.Cells["A2"].LoadFromCollection(selectStatement.ToString());
with
ws.Cells["A2"].LoadFromCollection(selectStatement, false);
After Edit3:
After this trial and error approaches, I decided to indeed lookup the EPPlus library you mentioned. I found out that you don't need any of this DynamicQuery. You can specify into LoadFromCollection the fields you want to show.
I didn't get to compile this (because it's your code) but It worked on my machine with fake data.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using InventoryTracker.DAL;
using OfficeOpenXml;
using InventoryTracker.Models;
using System.Reflection;
using OfficeOpenXml.Table;
namespace InventoryTracker.Controllers
{
public class ExportController : Controller
{
private InventoryTrackerContext _db = new InventoryTrackerContext();
[HttpPost]
public ActionResult ExportUsingEPPlus(ExportAssetsViewModel model)
{
//FileInfo newExcelFile = new FileInfo(output);
ExcelPackage package = new ExcelPackage();
var ws = package.Workbook.Worksheets.Add("TestExport");
var exportFields = new List<string>();
foreach (var selectedField in model.SelectedFields)
{
// Adds selected fields to [exportFields] List<string>
exportFields.Add(model.ListOfExportFields.First(s => s.Key == selectedField).Value);
}
// Loops to insert column headings into Row 1 of Excel
for (int i = 0; i < exportFields.Count(); i++)
{
ws.Cells[1, i + 1].Value = exportFields[i].ToString();
}
var membersToShow = typeof(INV_Asset).GetMembers()
.Where(p => exportFields.Contains(p.Name))
.ToArray();
ws.Cells["A2"].LoadFromCollection(_db.INV_Assets.ToList(), false, TableStyles.None, BindingFlags.Default, membersToShow);
var memoryStream = new MemoryStream();
package.SaveAs(memoryStream);
string fileName = "Exported-InventoryAssets-" + DateTime.Now + ".xlsx";
string contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
memoryStream.Position = 0;
return File(memoryStream, contentType, fileName);
}
}
}
1. TaskId property not exist in DynamicColumns class.
2. Remove .Replace("_", "") from
var taskColum = Enum.GetValues(typeof(EnumTasks)).Cast<EnumTasks>().Where(e => fieldIds.Contains("," + ((int)e).ToString() + ",")).Select(e => e.ToString().Replace("_", ""));
3.exportFields.Count should be > 0.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic;
namespace Dynamic
{
public class Program
{
public static List<DynamicColumns> DynamicColumnsCollection = new List<DynamicColumns>();
static Program()
{
for (int i = 0; i < 10; i++)
{
DynamicColumnsCollection.Add(new DynamicColumns() { Id = i, Name = "Name" + i, ip_address = "ip_" + i });
}
}
static void Main(string[] args)
{
IQueryable collection = DynamicSelectionColumns(new List<string>() { "id", "name" });
Console.ReadLine();
}
public class DynamicColumns
{
public int Id { get; set; }
public string Name { get; set; }
public string ip_address { get; set; }
}
public static IQueryable DynamicSelectionColumns(List<string> fieldsForExport)
{
if (!fieldsForExport.Any())
return null;
string select = string.Format("new ( {0} )", string.Join(", ", fieldsForExport.ToArray()));
var collection = DynamicColumnsCollection.Select(t => new DynamicColumns()
{
Id = t.Id,
Name = t.Name,
ip_address = t.ip_address,
}).ToList().AsQueryable().Select(select);
return collection;
}
}
}
Further any problem let me know.
Regards,
Ram.S
I have the following code which allows me to display the gridview exactly as I want,
I need to move the 2 form checkboxes to the same cell but that can be done after.
I am trying to update my database based on the editing done in the DGV, I have set Name, DOB/DOD, Place Of Death, Crem/Burial, Date of Funeral and COR to read only, these values do not need to update back.
Is there a way to map the DTO back to the entity framework or a better way again?
Thanks
private void RefreshDataGrid()
{
var query = (from f in context.funerals
where f.IsPencil == 0
join d in context.deceaseddetails on f.DeceasedID equals d.ID
join i in context.funeralservices on f.ID equals i.FuneralID
where i.IsAlternative == 0
join h in context.htvalues on f.HtValuesID equals h.ID
join p in context.placeofdeaths on f.PlaceOfDeathID equals p.ID
join c in context.coroners on f.CoronerID equals c.ID
let val1 = d.DateOfDeath
let val2 = d.DateOfBirth
let val3 = i.Date
orderby i.Date
select new
{
d.LastName,
d.FirstName,
val2,
val1,
f.CremOrInt,
FormsSigned1 = h.FormsSigned1,
FormsSigned2 = h.FormsSigned2,
PlaceOfDeath = p.PlaceOfDeath1.Substring(0, 15),
val3,
HospOrDocInformed = h.HospOrDocInformed ?? "Unspecified",
CHQorCoroner = h.CHQorCoroner ?? "Unspecified",
CertReq = h.CertReq ?? "Unspecified",
RestingAt = h.RestingAt ?? "Unspecified",
CoffinModel = h.CoffinModel ?? "Unspecified",
SizeAct = h.CoffinSize ?? "Unspecified",
CoffinPlateComp = h.CoffinPlateComp,
HtBy = h.HtBy ?? "Unspecified",
COR = c.Abbrieviation ?? "Unspecified",
Information = h.HTInformation ?? "Unspecified",
RedStatus = h.RedStatus,
YellowStatus = h.YellowStatus,
GreenStatus = h.GreenStatus
}).ToList();
var dataobjects = query.Select(d => new DataBindingProjection
{
DeceasedName = (d.FirstName + Environment.NewLine + d.LastName),
DOBDOD = (d.val2.HasValue ? d.val2.Value.ToShortDateString() : string.Empty) + Environment.NewLine +
(d.val1.HasValue ? d.val1.Value.ToShortDateString() : string.Empty),
DeathPlace = d.PlaceOfDeath,
CremInt = d.CremOrInt,
FuneralDate = (d.val3.HasValue ? d.val3.Value.ToShortDateString() : string.Empty),
HospDoc = d.HospOrDocInformed,
CHQCor = d.CHQorCoroner,
forms1 = d.FormsSigned1,
forms2 = d.FormsSigned2,
CertReq = d.CertReq,
RestingAt = d.RestingAt,
CoffinModel = d.CoffinModel,
SizeAct = d.SizeAct,
CoffinPlate = d.CoffinPlateComp,
HtBy = d.HtBy,
COR = d.COR,
Information = d.Information,
red = d.RedStatus,
yellow = d.YellowStatus,
green = d.GreenStatus
}).ToList();
dataGridView1.DataSource = dataobjects;
dataGridView1.Columns[0].HeaderText = "Last Name" + Environment.NewLine + "First Name";
dataGridView1.Columns[0].ReadOnly = true;
dataGridView1.Columns[1].HeaderText = "DOB" + Environment.NewLine + "DOD";
dataGridView1.Columns[1].ReadOnly = true;
dataGridView1.Columns[2].HeaderText = "Place Of" + Environment.NewLine + "Death";
dataGridView1.Columns[2].ReadOnly = true;
dataGridView1.Columns[3].HeaderText = "Crem/Int";
dataGridView1.Columns[3].ReadOnly = true;
dataGridView1.Columns[4].HeaderText = "Funeral" + Environment.NewLine + "Date";
dataGridView1.Columns[4].ReadOnly = true;
dataGridView1.Columns[5].HeaderText = "Hosp or" + Environment.NewLine + "Doc Informed";
dataGridView1.Columns[6].HeaderText = "CHQ or" + Environment.NewLine + "Coroner";
dataGridView1.Columns[7].HeaderText = "Forms 1" + Environment.NewLine + "Signed?";
dataGridView1.Columns[8].HeaderText = "Forms 2" + Environment.NewLine + "Signed?";
dataGridView1.Columns[9].HeaderText = "Cert" + Environment.NewLine + "Req.";
dataGridView1.Columns[10].HeaderText = "Resting" + Environment.NewLine + "#";
dataGridView1.Columns[11].HeaderText = "Coffin" + Environment.NewLine + "Model";
dataGridView1.Columns[12].HeaderText = "Size" + Environment.NewLine + "Act.";
dataGridView1.Columns[13].HeaderText = "Coffin" + Environment.NewLine + "Plate Comp";
dataGridView1.Columns[14].HeaderText = "HT" + Environment.NewLine + "By";
dataGridView1.Columns[15].HeaderText = "COR";
dataGridView1.Columns[15].ReadOnly = true;
dataGridView1.Columns[16].HeaderText = "Information" + Environment.NewLine + "Of Interest";
dataGridView1.Columns[17].HeaderText = "Red" + Environment.NewLine + "Status";
dataGridView1.Columns[18].HeaderText = "Yellow" + Environment.NewLine + "Status";
dataGridView1.Columns[19].HeaderText = "Green" + Environment.NewLine + "Status";
}
private class DataBindingProjection
{
public string DeceasedName { get; set; }
public string DOBDOD {get; set;}
public string DeathPlace { get; set; }
public string CremInt { get; set; }
public string FuneralDate { get; set; }
public string HospDoc { get; set; }
public string CHQCor { get; set; }
public Boolean forms1 { get; set; }
public Boolean forms2 { get; set; }
public string CertReq { get; set; }
public string RestingAt { get; set; }
public string CoffinModel { get; set; }
public string SizeAct { get; set; }
public Boolean CoffinPlate { get; set; }
public string HtBy { get; set; }
public string COR { get; set; }
public string Information { get; set; }
public Boolean red { get; set; }
public Boolean yellow { get; set; }
public Boolean green { get; set; }
}
Comment by Nilesh worked perfectly, thanks!
Use a Data Transfer Object then bind the DTO to the EF!