Compare 2 Columns in DataTable to 2 Columns in List and build a new List with certain criteria - c#

I have DataTable
public static DataTable SubProjects = new DataTable();
public static DataTable GetSubProjects
{
get { return SubProjects; }
}
it comes from database so columns are as follows
select ProjectN,ProjectSubN,ProjectM
and list:
public class SubProjectsList
{
public string ProjectNumber { get; set; }
public string SubProjectNumber { get; set; }
public string SubProjectName { get; set; }
public string ProjectManager { get; set; }
public int ObjectID { get; set; }
public SubProjectsList(string ProjectNumber, string SubProjectNumber, string SubProjectName, string ProjectManager, int ObjectID)
{
this.ProjectNumber = ProjectNumber;
this.SubProjectNumber = SubProjectNumber;
this.SubProjectName = SubProjectName;
this.ProjectManager = ProjectManager;
this.SubProjectNumber = SubProjectNumber;
this.ObjectID = ObjectID;
}
}
public static List<SubProjectsList> DeliverySubProjectList = new List<SubProjectsList>();
Ultimately I would like to get all results to new List where
ProjectN + ProjectSubN (DataTable) = ProjectNumber + SubProjectNumber (List) &&
ProjectM (DataTable) != ProjectManager (List)
As an output I need to get ProjectNumber, SubProjectNumber, ProjectM, ProjectManager. Basically I need to catch ProjectM and ProjectManager that does not match for one sub-project. I could have done it this way
var SubProjectResult = SubProjects.AsEnumerable()
.Where(x => DeliverySubProjectList.Any(y =>
y.ProjectNumber.Trim() + y.SubProjectNumber == x.Field<string>("ProjectN").Trim() + x.Field<string>("ProjectSubN").Trim() &&
!string.Equals(y.ProjectManager.Trim(), x.Field<string>("ProjectM").Trim(), StringComparison.CurrentCultureIgnoreCase)))
.Select(x => new
{
ProjectN = x.Field<string>("ProjectN"),
ProjectN = x.Field<string>("ProjectSubN"),
ProjectM = x.Field<string>("ProjectM"),
ProjectM = x.ProjectManager // This is not possible
})
.OrderBy(o => o.ProjectN).ToList();
but
ProjectM = x.ProjectManager // This is not possible
is wrong and does not compile. So I can't get ProjectManager from List where ProjectN + ProjectSubN (DataTable) = ProjectNumber + SubProjectNumber (List) match but ProjectManager does not match. Do I need to Concat DataTable and List together first? I have tried this
var myList1 = SubProjects.AsEnumerable().Concat(DeliverySubProjectList).ToList();
but getting an error
Severity Code Description Project File Line Suppression State
Error CS1929 'EnumerableRowCollection' does not contain a
definition for 'Concat' and the best extension method overload
'Queryable.Concat(IQueryable,
IEnumerable)' requires a receiver of type
'IQueryable'

I think this should give you what you are looking for. You might need to add extra null checks and I am also not very sure about that's how you want to add string values from the list and the data table:
public class ResultModel
{
public string ProjectNumber { get; set; }
public string SubProjectNumber { get; set; }
public string ProjectM { get; set; }
public string ProjectManager { get; set; }
}
...
...
static void Main(string[] args)
{
List<SubProjectsList> DeliverySubProjectList = // populate list
DataTable SubProjects = // populate datatable
List<ResultModel> results = GetResults(DeliverySubProjectList, SubProjects).ToList();
}
private static IEnumerable<ResultModel> GetResults(List<SubProjectsList> DeliverySubProjectList, DataTable SubProjects)
{
return SubProjects.AsEnumerable().Select(row =>
{
var listItem = DeliverySubProjectList.FirstOrDefault(item =>
{
return item.ProjectNumber + item.SubProjectNumber == row["ProjectN"].ToString() + row["ProjectSubN "].ToString()
&& !item.ProjectManager.Equals(row["ProjectM"].ToString());
});
if (listItem != null)
{
return new ResultModel
{
ProjectNumber = row["ProjectN"].ToString(),
SubProjectNumber = listItem.SubProjectNumber,
ProjectM = row["ProjectM"].ToString(),
ProjectManager = listItem.ProjectManager
};
}
else
{
return null;
}
})
.Where(res => res != null);
}

Related

Filter data from 2 lists with diferent models C#

I have this models
public class RoutingAttributeModel
{
public int Bus_No { get; set; }
public int Attribute_No { get; set; }
public string Attribute_Name { get; set; }
public string Status { get; set; }
public string Notes { get; set; }
}
public class AgentRoutingAttributeModel
{
public int Agent_No { get; set; }
public int Bus_No { get; set; }
public int Attribute_No { get; set; }
public string Attribute_Name { get; set; }
public string Status { get; set; }
}
List<RoutingAttributeModel> lstComplete = new List<RoutingAttributeModel>();
List<AgentRoutingAttributeModel> lstAssigned = new List<AgentRoutingAttributeModel>();
Filled this with some data
Is it possible to filter with Linq? I want to save in a new list the diferent content between lstComplete and lstAssigned
I was trying to join both lists but got stuck there
var results1 = from cl in lstComplete
join al in lstAssigned
on cl.Attribute_No equals al.Attribute_No
select cl;
you can use linq
as my understanding, you try to find linked by attribute_No records and have a list of not matching properties?
lstComplete.Add(new RoutingAttributeModel(){
Attribute_Name = "aaa",
Attribute_No = 1,
Bus_No = 1,
Notes = "",
Status = "status"
});
lstAssigned.Add(new AgentRoutingAttributeModel()
{
Attribute_No = 1,
Agent_No = 10,
Bus_No = 1,
Attribute_Name = "bbb",
Status = "status2"
});
var lst = lstComplete
.Join(lstAssigned,
complete => complete.Attribute_No,
assigned => assigned.Attribute_No,
(complete, assigned) => new { lstComplete = complete, lstAssigned = assigned })
.Select(s => new { s.lstComplete, s.lstAssigned})
.Where(w=>
w.lstAssigned.Attribute_Name != w.lstComplete.Attribute_Name
|| w.lstAssigned.Bus_No != w.lstComplete.Bus_No
)
.ToList()
.Dump();
so result would be
You could try the following query
var filteredList = lstComplete
.Where(x => !lstAssigned.Any(y => y.Attribute_No == x.Attribute_No));

How do I sort the csv file alphabetically and how to not show the "hidden" ones in the console with my code

I need to sort my csv file alphabetically and not show the ones that it says "hidden" for (aka. client 4 and client 5) this is the code:
static void Main(string[] args)
{
ReadCSFVFile();
Console.WriteLine();
}
static void ReadCSFVFile()
{
var lines = File.ReadAllLines("Navigation.txt");
var list = new List<Company>();
foreach (var line in lines)
{
var values = line.Split(';' );
var company = new Company() { ID = values[0], MenuName = values[1], ParentID = values[2], IsHidden = values[3], LinkURL = values[4] };
list.Add(company);
}
list.ForEach(x => Console.WriteLine($"{x.ID}\t {x.MenuName}\t {x.ParentID}\t {x.IsHidden}\t {x.LinkURL}"));
}
public class Company
{
public string ID { get; set; }
public string MenuName { get; set; }
public string ParentID { get; set; }
public string IsHidden { get; set; }
public string LinkURL { get; set; }
}
and this is the csv file:
ID;MenuName;ParentID;isHidden;LinkURL
1;Company;NULL;False; /company
2;About Us;1;False; /company/aboutus
3;Mission;1;False; /company/mission
4;Team;2;False; /company/aboutus/team
5;Client 2;10;False; /references/client2
6;Client 1;10;False; /references/client1
7;Client 4;10;True; /references/client4
8;Client 5;10;True; /references/client5
10;References;NULL;False; /references
The below should achieve this for you. I've commented the parts I've added to help out.
list.OrderBy(x => x.MenuName) // Order alphabetically based on MenuName
.Where(x => x.IsHidden != "True") // Filter only for non-hidden items
.ToList().ForEach(
x => Console.WriteLine($"{x.ID}\t {x.MenuName}\t {x.ParentID}\t{x.IsHidden}\t {x.LinkURL}"));

Add values to a list inside a list Linq

I am having a class like this.
public class CameraModel
{
public int JobId { get; set; }
public int ViewId { get; set; }
public Guid ViewGuid { get; set; }
public string Name { get; set; }
public int ViewNum { get; set; }
public int LayoutID { get; set; }
public List<CameraViewItemModel> CameraViewItems { get; set; }
}
The CameraViewItemModel class is like this:
public class CameraViewItemModel
{
public int JobID { get; set; }
public Guid ViewGuid { get; set; }
public int ViewID { get; set; }
public int CamNum { get; set; }
public Guid ChannelGuid { get; set; }
public string Name { get; set; }
public ActionType Action { get; set; }
}
Now, I am assigning the list of CameraViewItemModel like this:
// get all the cameramodel's
cameraModels = _unitOfWork.Context.CameraViews.Where(m => m.JobId == siteId)
.Select(m => new CameraModel
{
JobId = m.JobId,
ViewId = m.ViewId,
ViewGuid = m.ViewGuid,
Name = m.Name,
ViewNum = m.ViewNum,
LayoutID = m.LayoutId
}).ToList();
// get all the cameraviewitemmodels
cameraViewItemModels =
(from cameraView in _unitOfWork.Repository<CameraViews>().Get(x => x.JobId == siteId).Result
join cameraViewItem in _unitOfWork.Repository<CameraViewItems>().Get(x => x.JobId == siteId)
.Result on cameraView.ViewId equals cameraViewItem.ViewId into CameraViewItemResults
from cameraViewItemResult in CameraViewItemResults.DefaultIfEmpty()
join cameraChannel in _unitOfWork.Repository<CameraChannels>().Get(x => x.JobId == siteId)
.Result on (cameraViewItemResult == null ? new Guid() : cameraViewItemResult.ChannelGuid) equals cameraChannel.ChannelGuid into CameraChannelResults
from cameraChannelResult in CameraChannelResults.DefaultIfEmpty()
select new CameraViewItemModel
{
JobID = cameraView.JobId,
ViewID = cameraView.ViewId,
ViewGuid = cameraView.ViewGuid,
CamNum = cameraViewItemResult.CamNum,
ChannelGuid = cameraChannelResult.ChannelGuid,
Name = cameraChannelResult.Name
}).ToList();
// then do a 'join' on JobId, ViewId and ViewGuid and assign the list of cameraviewitemmodels to cameraModels.
foreach (var cameraModel in cameraModels)
{
cameraModel.CameraViewItems = (from cameraViewItem in cameraViewItemModels
where cameraModel.JobId == cameraViewItem.JobID
&& cameraModel.ViewId == cameraViewItem.ViewID
&& cameraModel.ViewGuid == cameraViewItem.ViewGuid
select cameraViewItem).ToList();
}
return cameraModels;
There are three tables in database:
CameraViews, CameraViewItems, CameraChannels.
CameraViews is the main table. It is left joined with CameraViewItems and CameraChannels to get the desired result. There may not be any data in CameraViewItems and CameraChannels for a corresponding CameraView.
Is it possible to assign the list of CameraViewItemModels to CameraModels in a single linq statement.
Here is a simple way to add values to a sub list, dunno if this is what you mean. You can keep selecting sub lists if that is necessary.
var parent_lst = new List<List<string>>(); // Root/parent list that contains the other lists
var sub_lst = new List<string>(); // Sub list with values
var selected_parent_lst = parent_lst[0]; // Here I select sub list, in this case by list index
selected_parent_lst.Add("My new value"); // And here I add the new value

Cannot implicitly convert type IQueryable to class

I am trying to get multiple results into a list to send back to JS to populate a grid. The first query (_mappedQuery) is getting data. I then want to end up putting the values into the _udfList object. I keep getting variances on the error 'cannot convert queryable to class'
I have tried setting as lists, creating query objects, single class objects. All no luck so far
MemberMNCFormsList _udfList = new MemberMNCFormsList();
foreach (var _row in _udfTables) {
System.Diagnostics.Debugger.Break();
System.Diagnostics.Debugger.Launch();
var _mappedQuery = (from res in Query<UdfColumnMapping>().AsNoTracking()
join udf in Query<UserDefinedForms>().AsNoTracking() on res.Func_Area equals udf.Func_Area
join ds in Query<Data_Set>().AsNoTracking() on res.Data_ID equals ds.DATA_ID
join df in Query<DEFITEM>().AsNoTracking() on ds.DEF_ID equals df.DEF_ID
where udf.UserDefinedForms_ID == _row.UserDefinedForms_ID &&
(res.FieldName.ToLower().StartsWith("reviewname") ||
res.FieldName.ToLower().StartsWith("disposition") ||
res.FieldName.ToLower().StartsWith("reviewdate"))
select (new MemberMNCForms {
UserDefinedFormData_ID = _row.UserDefinedFormData_ID,
FormId = udf.UserDefinedForms_ID,
MappedColumnName = res.MappedColumnName,
FieldName = res.FieldName,
MappedTableName = res.MappedTableName,
Reviewed_Name = _row.LAST_NAME.Trim() + ", " + _row.FIRST_NAME.Trim(),
Reviewed_Date = _row.CreateDate.GetShortDateorEmpty().ToString()
}));
var _formRow = _mappedQuery.Select(t => new MemberMNCForms {
UserDefinedFormData_ID = t.UserDefinedFormData_ID,
FormId = t.FormId,
MappedColumnName = t.MappedColumnName,
FieldName = t.FieldName,
MappedTableName = t.MappedTableName,
Reviewed_Name = t.Reviewed_Name,
Reviewed_Date = t.Reviewed_Date
})));
_udfList.list.Add(_formRow);
public sealed class MemberMNCForms {
public Guid? UserDefinedFormData_ID { get; set; }
public int FormId { get; set; }
public string Reviewed_Name { get; set; }
public string MappedColumnName { get; set; }
public string FieldName { get; set; }
public string MappedTableName { get; set; }
public int? MNCDetermination_ID { get; set; }
public string Reviewed_By { get; set; }
public string Reviewed_Date { get; set; }
}
public sealed class MemberMNCFormsList : ErrorInfo
{
public List<MemberMNCForms> list = new List<MemberMNCForms>();
public int Count { get; set; }
}
I am trying to get the _udfList object populated with the values coming from _mappedQuery. The only thing I thought would work was to create a MemberMNCForms object for each record in _mappedQuery to then add to _udfList.list
_formRow is an IEnumerable<MemberMNCForms>
var _formRow = _mappedQuery.Select(t => new MemberMNCForms {
UserDefinedFormData_ID = t.UserDefinedFormData_ID,
FormId = t.FormId,
MappedColumnName = t.MappedColumnName,
FieldName = t.FieldName,
MappedTableName = t.MappedTableName,
Reviewed_Name = t.Reviewed_Name,
Reviewed_Date = t.Reviewed_Date
})));
Here you are trying to add an IEnumerable<MemberMNCForms> to a List<MemberMNCForms>
_udfList.list.Add(_formRow);
You can't do this with .Add. You have to use .AddRange
Try this:
_udfList.list.AddRange(_formRow);
When you use linq like that, even if there is a single item in the list that you are Selecting on, it is just an expression tree until it is iterated on.
I assume that you are expecting a collection of MemberMNCForms back so you would need use AddRange instead of Add
_udfList.list.AddRange(_formRow);
To make sure that it has been executed, you can use ToList
_udfList.list.AddRange(_formRow.ToList());
If you are just expecting a single result, you can use SingleOrDefault.
var result = _formRow.SingleOrDefault();
if (result != null) {
_udfList.list.Add(result);
}

Converting Dataset to IList [duplicate]

This question already has answers here:
Convert DataSet to List
(11 answers)
Closed 8 years ago.
I am using SqlHelper to execute the stored procedure in the DB.
In a namespace called constants i defined something like this
public class ShowInstitutes
{
public string InstituteName { get; set; }
public string InstituteCity { get; set; }
public int InstituteId { get; set; }
}
In the DAL layer I am trying to execute stored proc and get results in IList format
public IList<ShowInstitutes> ShowInstitutes(int instituteId)
{
return SqlHelper.ExecuteDataset(dBConnection, "usp_SPName");
}
I am getting the following error:
Cannot implicitly convert type 'System.Data.DataSet' to 'System.Collections.Generic.IList<>
You can converting your Dataset result to IList like this.
public IList<ShowInstitutes> ShowInstitutes(int instituteId)
{
var dataTable = SqlHelper.ExecuteDataset(dBConnection, "usp_SPName");
var SourceLists = new List<ShowInstitutes>();
for (var index = 0; index < dataTable.Rows.Count; index++)
{
SourceLists.Add(new ShowInstitutes
{
InstituteName = Convert.ToString(dataTable.Rows[index]["Columnname"], CultureInfo.InvariantCulture),
InstituteCity = Convert.ToString(dataTable.Rows[index]["Columnname"], CultureInfo.InvariantCulture),
InstituteId = Convert.ToInt32(dataTable.Rows[index]["Columnname"], CultureInfo.InvariantCulture)
});
}
return SourceLists;
}
public IList<ShowInstitutes> ShowInstitutes(int instituteId)
{
var d = SqlHelper.ExecuteDataset(dBConnection, "usp_SPName");
var myData = d.Tables[0].AsEnumerable().Select(data => new ShowInstitutes{
InstituteName = data.Field<string>("InstituteName "),
InstituteCity = data.Field<string >("InstituteCity "),
InstituteId = data.Field<int>("InstituteId ")
});
var list = myData.ToList();
return list;
}
public class info
{
public string counter
{
get; set;
}
public string age
{
get;
set;
}
public string id
{
get;
set;
}
public string marks
{
get;
set;
}
public string name
{
get;
set;
}
public List<info> getdata()
{
string c = "Data Source=bla ;bla ;bla";
SqlConnection con = new SqlConnection(c);
DataSet ds = SqlHelper.ExecuteDataset(con, CommandType.Text, "SELECT * from table1");
var list = (ds.Tables[0].AsEnumerable().Select(
df =>
new info
{
age = df[0].ToString(),
counter = df[1].ToString(),
id = df[3].ToString(),
name = df[4].ToString(),
marks = df[2].ToString()
})).ToList();
return list;
}
}
class Program
{
static void Main(string[] args)
{
info a =new info();
List<info> list1= a.getdata();
foreach (var info in list1)
{
Console.WriteLine(info.name+" "+info.age+" "+info.marks);
}
Console.Read();
}
}

Categories