模型之间的 Linq 映射
我有一个实体框架的数据模型,其中一些实体具有可用于添加额外信息的属性集合。一些客户希望将这些属性映射到他们自己的域模型的“真实”属性。一个示例数据模型是:
public class DataEntity {
public Guid Id { get; set; }
public virtual ICollection<Attribute> Attributes { get; set; }
}
public class DataAttribute {
public Guid Id { get; set; }
public String Name { get; set; }
public String Value { get; set; }
}
public class DataStringAttribute : DataAttribute {
public String Value { get; set; }
}
public class DataInt32Attribute : DataAttribute {
public Int32 Value { get; set; }
}
一个示例域模型是:
public class DomainEntity {
public Guid Id { get; set; }
public String Name { get; set; }
public Int32 Age { get; set; }
}
我可以相当轻松地映射彼此之间的实体,但我希望能够在两者之间映射 Linq 表达式,以便在客户端中,它将是 IQueryable
,但这映射到 IQueryable
- 例如:
myDomainEntities.Where(o => o.Age > 21)
可以映射到:
myDataEntities.Where(o => o.Attributes.OfType<DataInt32Attribute>()
.Any(o => o.Name = "Age" && o.Value > 21);
最好的方法是什么 - 也许编写一个 QueryProvider遍历表达式树并将其转换为使用数据模型的树 - Linq-to-Linq-to-EntityFramework?
谢谢。
I have a data-model for Entity Framework in which some entities have a collection of attributes that can be used to add extra information. Some clients would like to map these attributes to 'real' properties of their own domain-model. An example data-model is:
public class DataEntity {
public Guid Id { get; set; }
public virtual ICollection<Attribute> Attributes { get; set; }
}
public class DataAttribute {
public Guid Id { get; set; }
public String Name { get; set; }
public String Value { get; set; }
}
public class DataStringAttribute : DataAttribute {
public String Value { get; set; }
}
public class DataInt32Attribute : DataAttribute {
public Int32 Value { get; set; }
}
And an example domain-model is:
public class DomainEntity {
public Guid Id { get; set; }
public String Name { get; set; }
public Int32 Age { get; set; }
}
I can fairly easily map the entities between eachother, but I would like to be able to map Linq expressions between the two so that in the client, it would be IQueryable<DomainEntity>
, but this is mapped to IQueryable<DataEntity>
- for example:
myDomainEntities.Where(o => o.Age > 21)
could be mapped to:
myDataEntities.Where(o => o.Attributes.OfType<DataInt32Attribute>()
.Any(o => o.Name = "Age" && o.Value > 21);
What would be the best way to do this - perhaps write a QueryProvider that walks the expression tree and translates it to one that uses the Data model - a Linq-to-Linq-to-EntityFramework?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你想做的事情是非典型的。您可能需要重写 Linq-to-Entity 提供程序并重写其查询生成功能。您将自己遍历表达式树,然后将该表达式树动态转换为 Linq-to-Entity 可以使用的新树,然后将该树传递给原始提供程序以进行查询生成。
换句话说,您正在劫持 Linq-to-Entity 来支持您的自定义格式。毛茸茸的,但如果你成功了,请写下来!我很高兴了解它是如何工作的!
另外,您知道您的客户端不会获得 Intellisense 支持,除非您也为 VS 编写自定义插件。该代码也会在 VS 中被标记为语法错误(我不确定它是否会编译)。这是因为类定义实际上没有改变——实体并不真正具有这些属性。
What you are trying to do is atypical. You might need to override the Linq-to-Entity provider and override its query-generation functionality. You'll be walking the expression tree yourself and then dynamically converting that expression tree to a new tree that Linq-to-Entity can work with, then pass that tree to the original provider for query-generation.
In other words, you are hijacking Linq-to-Entity to support your custom format. Hairy, but if you get it working, please write about it! I'd be glad to learn how it works!
Also, you understand that your client will not get Intellisense support though, unless you write you custom plugin for VS also. The code will also be flagged as syntax errors in VS (I am not sure whether it will compile). That is because the class definitions really didn't change -- the entities didn't really have those properties.