【问题标题】:How to Convert Anonymous Type to List <dynamic> using Linq to SQL in C#如何在 C# 中使用 Linq to SQL 将匿名类型转换为列表 <dynamic>
【发布时间】:2019-04-03 07:00:40
【问题描述】:

我是 C# 和 Linq 的新手。

实际上,我想将匿名类型返回到列表中。匿名类型包含 List、String 和 DateTime。我尝试使用下面的代码,但它给出了错误。请帮助并告诉我我缺少什么或建议我如何实现这一目标。

//错误:

System.InvalidCastException: Specified cast is not valid..

//编辑的 C# Linq 代码

        public List<AuditInfo> GetScanAudit(object Id, DateTime? fromTime, DateTime? toTime, string type = null,
            string user = null, Pager pager = null)
        {
            using (var ctx = new PlantDataContext())
            {
                var query = from audit in ctx.AuditLog
                            join ent in ctx.Scans on audit.RecordId equals ent.Id.ToString() into audits
                            from entaudits in audits.DefaultIfEmpty()
                            where audit.TypeFullName == "ABCD.DB.Model.Scan"
                            select new
                            {
                                audit,
                                entaudits
                            };

                if (Id != null)
                {
                    query = query.Where(x => x.audit.RecordId == Id.ToString());
                }
                if (fromTime.HasValue)
                {
                    var tmp = new DateTimeOffset(fromTime.Value.ToUniversalTime());
                    query = query.Where(x => x.audit.EventDateUTC >= tmp);
                }
                if (toTime.HasValue)
                {
                    var tmp = new DateTimeOffset(toTime.Value.ToUniversalTime());
                    query = query.Where(x => x.audit.EventDateUTC <= tmp);
                }
                if (!string.IsNullOrEmpty(type))
                {
                    var parseEvent = (EventType)Enum.Parse(typeof(EventType), type);
                    query = query.Where(x => x.audit.EventType == parseEvent);
                }
                if (!string.IsNullOrEmpty(user))
                {
                    query = query.Where(x => x.audit.UserName == user);
                }
                if (pager != null)
                {
                    var totalRecords = query.Count();
                    pager.TotalRecords = totalRecords;
                    var data = query.Select(x =>
                        new AuditInfo
                        {
                            x.audit.TypeFullName, //Here Error Occurs
                            x.audit.UserName,//Here Error Occurs
                            x.audit.EventType,//Here Error Occurs
                            x.audit.EventDateUTC,//Here Error Occurs
                            @LogDetails = x.audit.LogDetails.ToList(), //Here Error Occurs
                            x.entaudits.Name,
                            @Description = x.entaudits.Description
                        })
                        .OrderByDescending(x => x.EventDateUTC)
                        .Skip(pager.From)
                        .Take(pager.PageSize);
                    try
                    {
                        var list1 = data.ToList<AuditInfo>();
                    }
                    catch (Exception e)
                    {
                    }
                    var list = data.ToList<AuditInfo>();
                    pager.RecordCount = list.Count;
                    return list;
                }
                else
                {
                    var list = query.Select(x =>
                        new AuditInfo
                        {
                            x.audit.TypeFullName,
                            x.audit.UserName,
                            x.audit.EventType,
                            x.audit.EventDateUTC,
                            @LogDetails = x.audit.LogDetails.ToList(),
                            x.entaudits.Name,
                            @Description = x.entaudits.Description
                        })
                            .OrderByDescending(x => x.EventDateUTC)
                        .ToList<AuditInfo>();
                    return list;
                }
            }
        }

当我调试代码 totalRecords 变量显示计数 6,但显示异常消息时 Specified cast is not valid at this line var list1 = data.ToList();

【问题讨论】:

  • 不太确定 sql 标签是否与此处相关
  • @CaiusJard,似乎 OP 希望我们将 Linq 转换为 SQL。
  • 将方法的返回类型更改为其他类型:强类型类或 C#7 值元组。
  • 你想在哪里使用这个方法 => GetScanAudit 以及为什么选择返回类型List&lt;dynamic&gt; 和为什么不选择List&lt;SomeClass&gt;
  • 返回动态有什么意义? C# 是一种强类型编程语言,您的案例无需返回动态列表。如果您是 C# 新手,您应该知道强类型是好的,而您应该避免使用动态类型。

标签: c# linq anonymous-types


【解决方案1】:

您必须将匿名对象转换为动态对象。

要使用 linq 执行此操作,您可以使用 Cast&lt;dynamic&gt; linq 方法:

var list = query.Select(x =>
    new
    {
        x.audit.TypeFullName,
        x.audit.UserName,
        x.audit.EventType,
        x.audit.EventDateUTC,
        @LogDetails = x.audit.LogDetails.ToList(),
        x.entaudits.Name,
        @Description = x.entaudits.Description
    })
    .OrderByDescending(x => x.EventDateUTC)
    .AsEnumerable()
    .Cast<dynamic>()
    .ToList<dynamic>(); \\ here exception occures
return list;

【讨论】:

  • 不工作,先生。 EntityFramework.SqlServer.dll 中出现“System.NotSupportedException”类型的异常,但未在用户代码中处理其他信息:无法将“匿名类型”类型转换为“System.Object”类型。 LINQ to Entities 仅支持转换 EDM 基元或枚举类型。发生
  • @SandyN 你可以使用.AsEnumerable() 而不是.Cast&lt;dynamic&gt;
  • 还是不行,先生,An exception of type 'System.InvalidCastException' occurred in System.Data.dll but was not handled in user code Additional information: Specified cast is not valid. occurred
  • 使用 AsEnumerable()Cast&lt;dynamic&gt;() 对我有用
  • 效果很好!谢谢
【解决方案2】:

您可以为您的方法使用强返回类型,例如 List&lt;ClassName&gt; 而不是 List&lt;dynamic&gt;

public List<ClassName> GetScanAudit(object Id, DateTime? fromTime, DateTime? toTime, string type = null, string user = null, Pager pager = null)
{
   ...
}

那么你的查询将是

var data = query.Select(x =>
                new ClassName
                {
                    TypeFullName = x.audit.TypeFullName,
                    UserName = x.audit.UserName,
                    EventType = x.audit.EventType,
                    EventDateUTC = x.audit.EventDateUTC,
                    LogDetails = x.audit.LogDetails.ToList(),
                    Name = x.entaudits.Name,
                    Description = x.entaudits.Description
                })
                .OrderByDescending(x => x.EventDateUTC)
                .Skip(pager.From)
                .Take(pager.PageSize);

var list = data.ToList<ClassName>();

你的强类型类看起来像

public class ClassName
{
    public string TypeFullName { get; set; }
    public string UserName { get; set; }
    public string EventType { get; set; }
    public DateTime EventDateUTC { get; set; }
    public List<LogDetail> LogDetails { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
}

确保每个属性的数据类型应与查询中的.Select 子句匹配

编辑:

if (pager != null)
            {
                var totalRecords = query.Count();
                pager.TotalRecords = totalRecords;
                var data = query.Select(x =>
                    new AuditInfo
                    {
                        TypeFullName = x.audit.TypeFullName,
                        UserName = x.audit.UserName,
                        EventType = x.audit.EventType,
                        EventDateUTC = x.audit.EventDateUTC,
                        LogDetails = x.audit.LogDetails.ToList(),
                        Name = x.entaudits.Name,
                        Description = x.entaudits.Description
                    })
                    .OrderByDescending(x => x.EventDateUTC)
                    .Skip(pager.From)
                    .Take(pager.PageSize);
                try
                {
                    var list1 = data.ToList<AuditInfo>();
                }
                catch (Exception e)
                {
                }
                var list = data.ToList<AuditInfo>();
                pager.RecordCount = list.Count;
                return list;
            }
            else
            {
                var list = query.Select(x =>
                    new AuditInfo
                    {
                        TypeFullName = x.audit.TypeFullName,
                        UserName = x.audit.UserName,
                        EventType = x.audit.EventType,
                        EventDateUTC = x.audit.EventDateUTC,
                        LogDetails = x.audit.LogDetails.ToList(),
                        Name = x.entaudits.Name,
                        Description = x.entaudits.Description
                    })
                        .OrderByDescending(x => x.EventDateUTC)
                    .ToList<AuditInfo>();
                return list;
            }

【讨论】:

  • 谢谢先生,我会试试这个。
  • @SandyN,让我知道是否有帮助?
  • 好的,先生。我会的。
  • 确保 => 如果你 x.audit.TypeFullName 是字符串,那么在类中 TypeFullName 将是字符串,如果 x.audit.EventDateUTCDateTime 然后在类中 EventDateUTCDateTime 表示你必须为您的选择子句查询中应匹配的类属性分配正确的数据类型
  • 是的先生,我为此创建了另一个类文件
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-22
  • 2011-05-21
  • 2015-04-25
  • 2012-07-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多