linq C#对象列表类型根据条件更改

fivyi3re  于 2023-05-20  发布在  C#
关注(0)|答案(1)|浏览(133)

我正在使用Microsoft Blazor在.NET 6上开发复杂的应用程序。有许多类和许多函数以不同的方式操作List<Object>,但也有逻辑相同但List的<Object>类可能不同的情况。
例如,在下面的代码中有linq joins:

List<DataModel_STG_Table_Snapshot_Release_Ind> dataModel_STG_Table_Snapshot_Release_Inds = _dbContext.DataModel_STG_Table_Snapshot_Releases_Ind.Where(x => x.datamodel_id == y).ToList();
List<DataModel_STG_Table_Snapshot_Mapping_Ind> dataModel_STG_Table_Snapshot_Mapping_Inds = _dbContext.DataModel_STG_Table_Snapshot_Mappings_Ind.Where(x => x.datamodel_id == y).ToList();

var table_leftoutrtjoin = (
                from left in dataModel_STG_Table_Snapshot_Release_Inds
                join right in dataModel_STG_Table_Snapshot_Mapping_Inds
                on new { left.datamodel_stg_table_schm, left.datamodel_stg_table_name }
                equals new { right.datamodel_stg_table_schm, right.datamodel_stg_table_name }
                into ot
                from otnew in ot.DefaultIfEmpty()
                select new
                {
                    datamodel_stg_table_schm_raw = left.datamodel_stg_table_schm,
                    datamodel_stg_table_name_raw = left.datamodel_stg_table_name,

                    datamodel_stg_table_schm_ind = otnew?.datamodel_stg_table_schm,
                    datamodel_stg_table_name_ind = otnew?.datamodel_stg_table_name
                }).ToList();
                  

var table_rightouterjoin = (
                from left in dataModel_STG_Table_Snapshot_Mapping_Inds
                join right in dataModel_STG_Table_Snapshot_Release_Inds
                on new { left.datamodel_stg_table_schm, left.datamodel_stg_table_name }
                equals new { right.datamodel_stg_table_schm, right.datamodel_stg_table_name }
                into ot
                from otnew in ot.DefaultIfEmpty()
                select new
                {
                    datamodel_stg_table_schm_raw = otnew?.datamodel_stg_table_schm,
                    datamodel_stg_table_name_raw = otnew?.datamodel_stg_table_name,

                    datamodel_stg_table_schm_ind = left.datamodel_stg_table_schm,
                    datamodel_stg_table_name_ind = left.datamodel_stg_table_name
                }).ToList();

var table_model_lines = table_leftoutrtjoin.Concat(table_rightouterjoin);
table_model_lines = table_model_lines.Distinct().ToList(); //INNER MATCH DUPLICATION REMOVAL

上面描述的对象类如下:

public class DataModel_STG_Table_Ind
{
    [Key]
    public int datamodel_stg_table_id { get; set; }
    public int datamodel_id { get; set; }
    public string datamodel_stg_table_schm { get; set; } = null!;
    public string datamodel_stg_table_name { get; set; } = null!;
}

public class DataModel_STG_Table_Snapshot_Release_Ind
{
    [Key]
    public int datamodel_stg_table_id { get; set; }
    public int datamodel_id { get; set; }
    public string datamodel_stg_table_schm { get; set; } = null!;
    public string datamodel_stg_table_name { get; set; } = null!;
}

public class DataModel_STG_Table_Snapshot_Mapping_Ind
{
    [Key]
    public int datamodel_stg_table_id { get; set; }
    public int datamodel_id { get; set; }
    public string datamodel_stg_table_schm { get; set; } = null!;
    public string datamodel_stg_table_name { get; set; } = null!;
    public bool datamodel_stg_table_is_constructed { get; set; }
}

然后根据结果发生了几件事,但有时这个函数需要用不同的列表执行,我需要一种方法来改变列表,所以不是下面的:

List<DataModel_STG_Table_Snapshot_Release_Ind> dataModel_STG_Table_Snapshot_Release_Inds = _dbContext.DataModel_STG_Table_Snapshot_Releases_Ind.Where(x => x.datamodel_id == y).ToList();
List<DataModel_STG_Table_Snapshot_Mapping_Ind> dataModel_STG_Table_Snapshot_Mapping_Inds = _dbContext.DataModel_STG_Table_Snapshot_Mappings_Ind.Where(x => x.datamodel_id == y).ToList();

我可能有以下几个:

List<DataModel_STG_Table_Ind> dataModel_STG_Table_Inds = _dbContext.DataModel_STG_Tables_Ind.Where(x => x.datamodel_id == y).ToList();
List<DataModel_STG_Table_Snapshot_Release_Ind> dataModel_STG_Table_Snapshot_Release_Inds = _dbContext.DataModel_STG_Table_Snapshot_Releases_Ind.Where(x => x.datamodel_id == y).ToList();

请注意,List和List之间可能会发生切换<DataModel_STG_Table_Snapshot_Release_Ind><DataModel_STG_Table_Ind>(DataModel_STG_Table_Ind类具有DataModel_STG_Table_Snapshot_Release_Ind字段的子集字段,并且连接字段存在于两者上),因此是否有任何方法可以在不创建新函数并复制连接和其余代码的情况下完成此操作?
我在连接中尝试了类似的东西,因为我在列表上下文中有灵活性,而不是在数据库上下文中

(group_type.ForModeling() ? dataModel_STG_Table_Inds.ToList<DataModel_STG_Table_Snapshot_Release_Ind> : dataModel_STG_Table_Snapshot_Release_Inds)

但由于隐式转换而似乎不可能:

var table_leftoutrtjoin = (
                from left in (group_type.ForModeling() ? dataModel_STG_Table_Inds.ToList<DataModel_STG_Table_Snapshot_Release_Ind> : dataModel_STG_Table_Snapshot_Release_Inds)
                join right in dataModel_STG_Table_Snapshot_Mapping_Inds
                on new { left.datamodel_stg_table_schm, left.datamodel_stg_table_name }
                equals new { right.datamodel_stg_table_schm, right.datamodel_stg_table_name }
                into ot
                from otnew in ot.DefaultIfEmpty()
                select new
                {
                    datamodel_stg_table_schm_raw = left.datamodel_stg_table_schm,
                    datamodel_stg_table_name_raw = left.datamodel_stg_table_name,

                    datamodel_stg_table_schm_ind = otnew?.datamodel_stg_table_schm,
                    datamodel_stg_table_name_ind = otnew?.datamodel_stg_table_name
                }).ToList();
xpszyzbs

xpszyzbs1#

所以你现在看到的是利斯科夫替换校长。
为数据类型创建一个接口,只要你引用它,并且只引用类之间的公共属性,即接口中定义的那些属性,你就可以使用任何你想要的逻辑。
例如:

public interface IDataModel_STG_Table
{
    int datamodel_stg_table_id { get; set; }
    int datamodel_id { get; set; }
    string datamodel_stg_table_schm { get; set; }
    string datamodel_stg_table_name { get; set; }
}

public class DataModel_STG_Table_Ind : IDataModel_STG_Table
{
    public int datamodel_stg_table_id { get; set; }
    public int datamodel_id { get; set; }
    public string datamodel_stg_table_schm { get; set; }
    public string datamodel_stg_table_name { get; set; }
}

public class DataModel_STG_Table_Snapshot_Release_Ind : IDataModel_STG_Table
{
    public int datamodel_stg_table_id { get; set; }
    public int datamodel_id { get; set; }
    public string datamodel_stg_table_schm { get; set; }
    public string datamodel_stg_table_name { get; set; }
}

public class DataModel_STG_Table_Snapshot_Mapping_Ind : IDataModel_STG_Table
{
    public int datamodel_stg_table_id { get; set; }
    public int datamodel_id { get; set; }
    public string datamodel_stg_table_schm { get; set; }
    public string datamodel_stg_table_name { get; set; }
    public bool datamodel_stg_table_is_constructed { get; set; }
}

这样,列表就不再被指定为包含具体的类,而是包含实现接口的类的示例。因此,它们的填充方式如下:

List<IDataModel_STG_Table> dataModel_STG_Table_Snapshot_Release_Inds = _dbContext.DataModel_STG_Table_Snapshot_Releases_Ind.Where(x => x.datamodel_id == y).ToList();
List<IDataModel_STG_Table> dataModel_STG_Table_Snapshot_Mapping_Inds = _dbContext.DataModel_STG_Table_Snapshot_Mappings_Ind.Where(x => x.datamodel_id == y).ToList();

List<IDataModel_STG_Table> dataModel_STG_Table_Inds = _dbContext.DataModel_STG_Tables_Ind.Where(x => x.datamodel_id == y).ToList();
List<IDataModel_STG_Table> dataModel_STG_Table_Snapshot_Release_Inds = _dbContext.DataModel_STG_Table_Snapshot_Releases_Ind.Where(x => x.datamodel_id == y).ToList();

现在,您可以将连接代码放在函数中,如

public IEnumerable<IDataModel_STG_Table> LeftJoinTables(List<IDataModel_STG_Table> table1, List<IDataModel_STG_Table> table2)

然后调用using

var result = LeftJoinTables(dataModel_STG_Table_Snapshot_Release_Inds, dataModel_STG_Table_Snapshot_Mapping_Inds);

var result = LeftJoinTables(DataModel_STG_Table_Inds, dataModel_STG_Table_Snapshot_Mapping_Inds);

您可能需要对联接代码进行一些调整,以确保返回类型为IEnumerable<IDataModel_STG_Table>,但这将包括实现IEnumerable的任何集合类型,包括List<IDataModel_STG_Table>
调用逻辑知 prop 体的类类型是什么,但是我会谨慎地使用DataModel_STG_Table_Snapshot_Mapping_Ind转换任何结果,因为这包括接口中不存在的字段/属性。

相关问题