本文介绍了LINQ到实体 - 建筑where子句测试中的许多藏品一对多的关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我使用LINQ的实体框架。我有2个实体:内容标签。它们与彼此多对多的关系。 内容可以有很多的标签标签可以有多个目录。所以,我想编写一个查询来选择所有内容,其中的任何标记名称等于等等

So, I am using the Linq entity framework. I have 2 entities: Content and Tag. They are in a many-to-many relationship with one another. Content can have many Tags and Tag can have many Contents. So I am trying to write a query to select all contents where any tags names are equal to blah

的实体都具有其它实体作为属性(但没有编号)的集合。这是我在挣扎。我确实有自定义前pression包含(所以,谁就可能帮助我,你可以认为我可以做一个包含一个集合)。我得到这个前pression来自:<一href=\"http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2670710&SiteID=1\">http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2670710&SiteID=1

The entities both have a collection of the other entity as a property(but no IDs). This is where I am struggling. I do have a custom expression for Contains (so, whoever may help me, you can assume that I can do a "contains" for a collection). I got this expression from: http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2670710&SiteID=1

I最终找到我自己的答案。

推荐答案

阅读有关,阅读完所有的人发给我的精彩帖子,发布在其他网站上,然后阅读更多的<一个href=\"http://blogs.msdn.com/meek/archive/2008/05/02/linq-to-entities-combining-$p$pdicates.aspx\">Combining predicates 和 ..呵呵,我拿起从(其中的一些类是从这些页面获取)。

After reading about the PredicateBuilder, reading all of the wonderful posts that people sent to me, posting on other sites, and then reading more on Combining Predicates and Canonical Function Mapping.. oh and I picked up a bit from Calling functions in LINQ queries (some of these classes were taken from these pages).

我终于有了一个解决方案!虽然有是有点砍死了一块...

I FINALLY have a solution!!! Though there is a piece that is a bit hacked...

让我们得到了一块砍死在与:(

Let's get the hacked piece over with :(

我不得不使用反射器和复制标记为内部防爆pressionVisitor类。然后我不得不作出它的一些细微的变化,要得到它的工作。我不得不创建两个例外(因为它是newing内部异常我也不得不改变ReadOnlyCollection还()方法的回报来自:

I had to use reflector and copy the ExpressionVisitor class that is marked as internal. I then had to make some minor changes to it, to get it to work. I had to create two exceptions (because it was newing internal exceptions. I also had to change the ReadOnlyCollection() method's return from:

return sequence.ToReadOnlyCollection<Expression>();

要:

return sequence.AsReadOnly();

我会发布类,但它是相当大的,我不希望扰乱这个帖子任何比它已经将是。我希望在未来的类可以从我的媒体库中删除,而微软将使其公开。谈完...

I would post the class, but it is quite large and I don't want to clutter this post any more than it's already going to be. I hope that in the future that class can be removed from my library and that Microsoft will make it public. Moving on...

我添加了一个ParameterRebinder类:

I added a ParameterRebinder class:

public class ParameterRebinder : ExpressionVisitor {
    	private readonly Dictionary<ParameterExpression, ParameterExpression> map;

    	public ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map) {
    		this.map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
    	}

    	public static Expression ReplaceParameters(Dictionary<ParameterExpression, ParameterExpression> map, Expression exp) {
    		return new ParameterRebinder(map).Visit(exp);
    	}

    	internal override Expression VisitParameter(ParameterExpression p) {
    		ParameterExpression replacement;
    		if (map.TryGetValue(p, out replacement)) {
    			p = replacement;
    		}
    		return base.VisitParameter(p);
    	}
    }

然后我加了一个前pressionExtensions类:

Then I added a ExpressionExtensions class:

public static class ExpressionExtensions {
    	public static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second, Func<Expression, Expression, Expression> merge) {
    		// build parameter map (from parameters of second to parameters of first)
    		var map = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);

    		// replace parameters in the second lambda expression with parameters from the first
    		var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);

    		// apply composition of lambda expression bodies to parameters from the first expression 
    		return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
    	}

    	public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second) {
    		return first.Compose(second, Expression.And);
    	}

    	public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second) {
    		return first.Compose(second, Expression.Or);
    	}
    }

和我加了最后一节课是predicateBuilder:

And the last class I added was PredicateBuilder:

public static class PredicateBuilder {
	public static Expression<Func<T, bool>> True<T>() { return f => true; }
	public static Expression<Func<T, bool>> False<T>() { return f => false; }

}

这是我的结果...我能执行此code和取回所产生的内容的实体有从我在寻找!

This is my result... I was able to execute this code and get back the resulting "content" entities that have matching "tag" entities from the tags that I was searching for!

	public static IList<Content> GetAllContentByTags(IList<Tag> tags) {
		IQueryable<Content> contentQuery = ...

		Expression<Func<Content, bool>> predicate = PredicateBuilder.False<Content>();

		foreach (Tag individualTag in tags) {
			Tag tagParameter = individualTag;
			predicate = predicate.Or(p => p.Tags.Any(tag => tag.Name.Equals(tagParameter.Name)));
		}

		IQueryable<Content> resultExpressions = contentQuery.Where(predicate);

		return resultExpressions.ToList();
	}

请让我知道,如果有人需要帮助,同样的事情,如果你想我给你发送文件,对于这一点,或者只是需要更多的信息。

Please let me know if anyone needs help with this same thing, if you would like me to send you files for this, or just need more info.

这篇关于LINQ到实体 - 建筑where子句测试中的许多藏品一对多的关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 00:34