小编Mil*_*vic的帖子

动态地将IEnumerable转换为IQueryable或使用LINQ表达式动态调用AsQueryable

我正在动态创建LINQ查询,到目前为止我做得很好.

但我被困在我认为不会的地方.在构建该查询的某个点上,我需要访问实体的EnityCollection.像这样的东西:

Expression collection = Expression.Property(entity, typeof(EntityType).GetProperty("CollectionOfRelatedEntities"));
Run Code Online (Sandbox Code Playgroud)

然后,我会在该集合上调用"Where"LINQ方法:

MethodCallExpression AfterWhere = Expression.Call(
                        typeof(Queryable),
                        "Where",
                        new Type[] { typeof(RelatedEntity) },
                        collection,
                        Expression.Lambda<Func<RelatedEntity, bool>>(predicate, new ParameterExpression[] { paramOfRelatedEntity }));
Run Code Online (Sandbox Code Playgroud)

通常这会奏效.在这种情况下它不会因为集合是IEnumerable而我需要它是IQueryable以便"Where"工作.

我试过这个:

Expression.Convert(collection, typeof(IQueryable<RelatedEntity>);
Run Code Online (Sandbox Code Playgroud)

但它说无法转换,因为EntityCollection没有实现IQueryable.

我静态地使用AsQueryable来实现我在这里需要的东西,所以我尝试动态地模仿它:

Expression.Call(collection, typeof(EntityCollection<RelatedEntity>).GetMethod("AsQueryable"));
Run Code Online (Sandbox Code Playgroud)

但我得到null引用异常.我无法通过反思达到它.这个AsQueryable方法是扩展方法,它是静态的,在Queryable类中定义,所以我试过:

Expression.Call(collection, typeof(Queryable).GetMethod("AsQueryable", BindingFlags.Static)); 
Run Code Online (Sandbox Code Playgroud)

相同的结果:"值不能为空".

我在这里达到了极限,我的想法很新鲜.

所以,我问你:

如何动态地将IEnumerable转换为IQueryable?

c# linq dynamic

8
推荐指数
1
解决办法
7741
查看次数

动态设置Func <>类型

有没有办法Func<>动态设置类型参数,所以我不必使用无穷无尽的if语句?

就像是:

Type t = Type.GetType("System.Decimal");
Func<t> foo = new Func<t>(some_function);
Run Code Online (Sandbox Code Playgroud)

代替:

Func<Decimal> foo = new Func<Decimal>(some_function);
Run Code Online (Sandbox Code Playgroud)

更新:

这是我代码中的代码段:

Type t = typeof(StavkaDokumenta).GetProperty(pd.Polje).PropertyType;
ParameterExpression pe = Expression.Parameter(typeof(StavkaDokumenta), "stavka");
Expression expr = Expressions.ResolveCompleteExpression(pe, pd.Expression);
Expression final = Expression.Convert(expr, t);
if (t == typeof(decimal))
{
    var lambda = Expression.Lambda<Func<StavkaDokumenta, decimal>>(final, pe);
    o = lambda.Compile().Invoke(stavka);
}
if (t == typeof(decimal?))
{
    var lambda = Expression.Lambda<Func<StavkaDokumenta, decimal?>>(final, pe);
    o = lambda.Compile().Invoke(stavka);
}
else if (t == typeof(int))
{
    var lambda …
Run Code Online (Sandbox Code Playgroud)

c# types func

8
推荐指数
1
解决办法
4839
查看次数

在任意IQueryable <T>上获取Count()LINQ扩展方法的MethodInfo

我有IQueryable <T>源,我想动态调用IQueryable <T> .Count().

所以,我需要在IQueryable中声明的Count方法的MethodInfo.

这是来自msdn的签名(在IQueryable <>中):

public static int Count<TSource>(
    this IQueryable<TSource> source
)
Run Code Online (Sandbox Code Playgroud)

这是我有多远:

Expression expr; //this is expression which holds my IQueryable<T>
MethodInfo mi = expr.Type.GetMethod("Count", BindingFlags.Static | BindingFlags.Public, null, new[] { expr.Type }, null); 
Run Code Online (Sandbox Code Playgroud)

但我的mi总是空的;

我也尝试过:

mi = typeof(IQueryable<>).GetMethod("Count", BindingFlags.Static | BindingFlags.Public, null, new[] { expr.Type }, null);
Run Code Online (Sandbox Code Playgroud)

但又是空的.

我的最终目标是:

Expression.Call(mi, expr);
Run Code Online (Sandbox Code Playgroud)

更新:这是我得到Sum Extension方法的方法:

MethodInfo sum = typeof(Queryable).GetMethod("Sum", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(IQueryable<decimal>) }, null);
Run Code Online (Sandbox Code Playgroud)

这是有效的,但这个Sum方法不是通用的.它虽然是静态的.

c# linq iqueryable count

8
推荐指数
1
解决办法
1708
查看次数

实体框架检查属性是否为导航属性

有没有办法从其元数据中查看实体的属性是否为导航属性?

我可以通过检查属性是否实现ICollection来确定属性是否是实体集合,从那里我可以断定它是否是导航属性.

但是,如果属性不是实体集合而只是引用另一个实体呢?

properties entity-framework-4

5
推荐指数
1
解决办法
3119
查看次数

更新到MVC5后找不到/ signalr/hubs 404

SignalR正在工作,而项目是ASP.NET MVC3.现在我将它升级到MVC5(不是那么容易做,我必须告诉你).

然后我注意到signalR没有工作.我按照这本书,将SignalR重新安装到版本2.1.0,安装了OWIN(必须为v2 +)并为项目添加了启动类.

这是我的startup.cs类,它位于项目根文件夹中:

[assembly: OwinStartup(typeof(SISTEM.Startup))]
namespace SISTEM
{
    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.MapSignalR();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我觉得这里没问题,但也许我错过了什么......

现在这里是来自集线器的片段:

namespace SISTEM
{
    public class PostingHub : Hub
    {
        public void Test(string hello)
        {
            Clients.All.hello(hello);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我在视图中引用生成的代理:

<script src="~/Scripts/jquery.signalR-2.1.0.min.js"></script>
<script src="~/signalr/hubs"></script>
Run Code Online (Sandbox Code Playgroud)

我在fiddler中检查它,我可以看到/ signalr/hubs请求正在生成未找到的HTTP 404.

现在,我并不懒惰,我尝试了几件事:

  • 修补无扩展URL的IIS - 因为我使用的是win8,所以不应该成为问题
  • 在RegisterRoutes(RouteTable.Routes)之前调用RouteTable.Routes.MapHubs() - VS将不允许它.给我一个错误,说已经过时,使用OWIN.
  • 下载的工具用于生成JavaScript代理(SignarR Utils),所以我可以稍后手动引用它们.试图生成,没有错误,但生成的js是空的.试了好几次.这对我来说最有趣.也许由于某种原因无法生成代理.

任何帮助,将不胜感激.

更新:来自/ signalr/hubs的响应

<!DOCTYPE html>
<html>
<head>
    <title>The resource cannot be found.</title>
    <meta name="viewport" content="width=device-width" />
</head>

<body bgcolor="white">

        <span><H1>Server …
Run Code Online (Sandbox Code Playgroud)

c# asp.net-mvc proxy signalr

5
推荐指数
1
解决办法
7593
查看次数

Crystal Reports 和登录问题

我需要帮助。

实际上,我已经阅读了有关此问题的信息,并且我认为我已经解决了它,但它一直困扰着我。

这是关于开发和生产环境中的不同登录。

这应该是解决方案(EF和SQL Server):

SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder((model.Connection as EntityConnection).StoreConnection.ConnectionString);

ConnectionInfo ci = new ConnectionInfo();

ci.ServerName = builder.DataSource;
ci.DatabaseName = builder.InitialCatalog;
ci.UserID = builder.UserID;
ci.Password = builder.Password;

report.SetDatabaseLogon(ci.UserID, ci.Password, builder.DataSource, ci.DatabaseName);

foreach (CrystalDecisions.CrystalReports.Engine.Table tbl in report.Database.Tables)
{
    TableLogOnInfo logon = tbl.LogOnInfo;
    logon.ConnectionInfo = ci;
    tbl.ApplyLogOnInfo(logon);
}
Run Code Online (Sandbox Code Playgroud)

我从实体连接中提取登录信息并将其应用于报表中的所有表。这应该够了吧。我添加 SetDatabaseLogon() 只是为了确定,但这不是必需的。

现在,当我在生产环境中运行报告时,报告会弹出一个数据库登录屏幕,显示正确的服务器名称(生产服务器),数据库旁边没有任何内容(这是我所关心的),正确的用户名,没有密码,要求输入登录信息.

我输入了,但 CR 显示“登录失败。请重试”。我的意思是WTF。我使用相同的凭据通过 Management Studio 连接到数据库。

我正在使用 WPF 查看器,顺便说一句。

我真的被困在这里,我已经做了一些调试,并且连接信息获得了所有正确的数据,所以必须报告谁是罪魁祸首,但我该怎么办?

任何帮助,将不胜感激。我希望有人在我之前偶然发现了同样的问题。

问候

c# sql-server entity-framework crystal-reports

3
推荐指数
1
解决办法
7675
查看次数

当编译时类型未知时,将对象动态转换为类型

我有一种从数据库获取数据的方法,它是通用的:

public static IQueryable<T> GetData<T>(IQueryable<T> data, some more parameters)
Run Code Online (Sandbox Code Playgroud)

data 是未过滤的数据库实体集合,而 GetData 会对该集合进行过滤、排序、跳过、处理...

当我像平常一样提供 IQueryable 类型的变量(T 是 Document)作为第一个参数时,它当然可以工作:

IQueryable<Document> data = ... 
GetData<Document>(data, ....);
Run Code Online (Sandbox Code Playgroud)

现在,我需要动态“计算”第一个参数。为此,我使用 LINQ 表达式,它将计算为 IQueryable,但我不知道编译时是哪个 T。我在想这样的事情:

Expression db = Expression.Constant(new DataModelContainer());
Expression table = Expression.Property(db, tbl); /* tbl = "Documents", this is the whole point */ 
Type type = table.Type.GetGenericArguments()[0];
Expression call = Expression.Call(typeof(Queryable), "AsQueryable", new Type[] { type }, table);            
object o = Expression.Lambda(call, null).Compile().DynamicInvoke();
Run Code Online (Sandbox Code Playgroud)

此时,确实是 IQueryable (IQueryable),因此应该能够作为 GetData 的参数。但是,我只有“对象”引用它,自然不能那样使用它。

所以,我的问题是:当 o 正是这样时,有什么方法可以动态地将 'o' 转换为 'IQueryable' …

c# linq expression casting

3
推荐指数
1
解决办法
2649
查看次数

无法通过CancellationTokenSource.Cancel()取消任务

我无法阻止任务.首先,我刚开始使用任务.以前,我一直在使用delegate.BeginInvoke()在后台运行,但这次我需要停止后台执行,如果需要的话.所以我切换到了任务.这是我的代码:

CancellationTokenSource token = new CancellationTokenSource();
Task posting = Task.Factory.StartNew(() => DoPosting(docs, session), token.Token);
HttpRuntime.Cache[session.ToString() + "_token"] = token;
HttpRuntime.Cache[session.ToString() + "_task"] = posting;
Run Code Online (Sandbox Code Playgroud)

这是ASP.NET MVC,所以我在HttpRuntime.Cache中存储了持久的东西.用户可以通过此操作取消操作:

public JsonResult StopPosting(string session)
{
    CancellationTokenSource token = (CancellationTokenSource)HttpRuntime.Cache.Get(session.ToString() + "_token");
    Task posting = (Task)HttpRuntime.Cache[session.ToString() + "_task"];
    token.Cancel();

    return Json(new { Message = "Stopped!" });
}
Run Code Online (Sandbox Code Playgroud)

现在,当这个动作第一次被击中时,没有任何反应.然后我第二次要求取消.现在,token.IsCancellationRequested说"true",所以token.Cancel()必须做一些事情.但是发布.Status仍然是"正在运行".它会保持这种状态直到它完成,然后它是"RunToCompletion".

所以,我要求取消任务,但它没有被取消.

也许我做错了什么或者我错过了一些明显的东西,但我无法看到/理解为什么它不会取消.

也许有人可以解释一下?

问候.

c# multithreading task task-parallel-library

3
推荐指数
1
解决办法
1782
查看次数

通过 Linq.Expressions 和 Lambda 进行 GroupBy 查询

我需要的是通过 Linq.Expressions 表示此查询:

db.Documents.GroupBy(a => 1).Select(b => b.Sum(c => c.Amount) });
Run Code Online (Sandbox Code Playgroud)

这是我到目前为止所拥有的:

IQueryable<Document> data = db.Documents;

ParameterExpression pe = Expression.Parameter(typeof(Document), "doc");

Expression groupBy = Expression.Call(
    typeof(Queryable),
    "GroupBy",
    new Type[] { typeof(Document), typeof(int) },
    data.Expression,
    Expression.Lambda(Expression.Constant(1), pe));

ParameterExpression peg = Expression.Parameter(typeof(IGrouping<int, Document>), "group");

Expression select = Expression.Call(
    typeof(Queryable),
    "Select",
    new Type[] { typeof(IGrouping<int, Document>), typeof(int) },
    groupBy,
    Expression.Lambda(Expression.Property(peg, "Key"), peg));

foreach (var item in data.Provider.CreateQuery(select)) { ... }
Run Code Online (Sandbox Code Playgroud)

这是执行:

db.Documents.GroupBy(a => 1).Select(b => b.Key });
Run Code Online (Sandbox Code Playgroud)

而且效果很好。现在,我想聚合一个总和,而不是访问组的密钥。

这对我来说是棘手的地方。我在想这样的事情:

ParameterExpression pe1 = Expression.Parameter(typeof(Document), …
Run Code Online (Sandbox Code Playgroud)

c# linq lambda expression

2
推荐指数
1
解决办法
1304
查看次数

System.Threading.Timer不会触发

我是新来的...

我有一个问题,如果有人可以帮助我.

它是关于计时器(System.Threading.Timer).

我想打破不可避免的递归:我在datarow中有两列,它们是相互依赖的(price_without_VAT和price_with_VAT).设置其中一个肯定会导致StackOverflowException.所以这就是这个想法:

bool flag = true;
void Reset(object state) { flag = true; }
Run Code Online (Sandbox Code Playgroud)

现在,包装用于更改其中一列的值的方法:

{
    if(flag)
    {
        flag = false;
        System.Threading.Timer tmr = new System.Threading.Timer(new System.Threading.TimerCallback(Reset), null, 10, System.Threading.Timeout.Infinite);
        datarow.other_column = value;
    }
}
Run Code Online (Sandbox Code Playgroud)

datarow.other_column.value行将立即触发上述方法,但不会有递归,因为flag为false.在10毫秒标志应该回到真,一切都恢复正常.

现在,当我按照DEBUGGER中的代码进行操作时,一切正常,但是当我启动应用程序NORMALLY重置功能根本不会触发,标志永远停留在虚假状态,并且一切都是假的.我玩弄due_time参数但似乎没有任何帮助.

有任何想法吗?

c# timer

1
推荐指数
1
解决办法
1322
查看次数