我已经开始从事一个 MVC 3 项目,该项目需要来自庞大的现有数据库的数据。
我的第一个想法是继续使用 EF 4.1 并创建一堆 POCO 来表示我需要的表,但我开始认为映射会变得过于复杂,因为我只需要某些表中的某些列表格。(感谢 Steven 在评论中进行澄清。
所以我想我应该给大规模 ORM 尝试一下,我通常使用工作单元实现,这样我就可以使所有内容很好地解耦。使用依赖注入。这是我对 Massive 的一部分:
public interface ISession
{
DynamicModel CreateTable<T>() where T : DynamicModel, new();
dynamic Single<T>(string where, params object[] args)
where T : DynamicModel, new();
dynamic Single<T>(object key, string columns = "*")
where T : DynamicModel, new();
// Some more methods supported by Massive here
}
这是我对上述接口的实现:
public class MassiveSession : ISession
{
public DynamicModel CreateTable<T>() where T : DynamicModel, new()
{
return new T();
}
public dynamic Single<T>(string where, params object[] args)
where T: DynamicModel, new()
{
var table = CreateTable<T>();
return table.Single(where, args);
}
public dynamic Single<T>(object key, string columns = "*")
where T: DynamicModel, new()
{
var table = CreateTable<T>();
return table.Single(key, columns);
}
}
问题出在 First()
、Last()
和FindBy()
方法基于名为 DynamicModel
的动态
对象,并且不定义任何上面的方法;它通过从 TryInvokeMethod() 实现来处理它们rel="nofollow noreferrer">DynamicObject
相反:
public override bool TryInvokeMember(InvokeMemberBinder binder,
object[] args, out object result) { }
我不知道如何在我的 ISession
中“连接”这些方法。我的 ISession
如何提供对 First()
、Last()
和 FindBy()
的支持?
换句话说,我如何使用 Massive 的所有功能,同时仍然能够将我的类与数据访问分离?
I've started working on an MVC 3 project that needs data from an enormous existing database.
My first idea was to go ahead and use EF 4.1 and create a bunch of POCO's to represent the tables I need, but I'm starting to think the mapping will get overly complicated as I only need some of the columns in some of the tables. (thanks to Steven for the clarification in the comments.
So I thought I'd give Massive ORM a try. I normally use a Unit of Work implementation so I can keep everything nicely decoupled and can use Dependency Injection. This is part of what I have for Massive:
public interface ISession
{
DynamicModel CreateTable<T>() where T : DynamicModel, new();
dynamic Single<T>(string where, params object[] args)
where T : DynamicModel, new();
dynamic Single<T>(object key, string columns = "*")
where T : DynamicModel, new();
// Some more methods supported by Massive here
}
And here's my implementation of the above interface:
public class MassiveSession : ISession
{
public DynamicModel CreateTable<T>() where T : DynamicModel, new()
{
return new T();
}
public dynamic Single<T>(string where, params object[] args)
where T: DynamicModel, new()
{
var table = CreateTable<T>();
return table.Single(where, args);
}
public dynamic Single<T>(object key, string columns = "*")
where T: DynamicModel, new()
{
var table = CreateTable<T>();
return table.Single(key, columns);
}
}
The problem comes with the First()
, Last()
and FindBy()
methods. Massive is based around a dynamic
object called DynamicModel
and doesn't define any of the above method; it handles them through a TryInvokeMethod()
implementation overriden from DynamicObject
instead:
public override bool TryInvokeMember(InvokeMemberBinder binder,
object[] args, out object result) { }
I'm at a loss on how to "interface" those methods in my ISession
. How could my ISession
provide support for First()
, Last()
and FindBy()
?
Put it another way, how can I use all of Massive's capabilities and still be able to decouple my classes from data access?
发布评论
评论(2)
我知道这个问题已经得到解答 - 但是 Massive 中的每个方法都被标记为虚拟的,因此您可以轻松地模拟它。我可能会建议这样做。或者 - 别打扰。
我目前正在我的项目中为 MVC3 视频执行此操作,并从 Rails 的剧本中获取页面 - 将我的查询作为对象上的静态方法提供,然后从那里开始。我让我的测试命中数据库 - 它根本不会减慢速度,并且可以轻松摆脱所有机器。
Rails 中没有 DI/IoC,这是一种幸福的感觉。
I know this question has been answered - but every method in Massive is marked as virtual so you can Mock it easily. I might suggest that. OR - don't bother.
I'm doing this on my project currently for the MVC3 videos and taking a page from the Rails' playbook - offer my queries as static methods on my objects and go from there. I let my tests hit the database - it doesn't slow things down at all and is quite freeing to get rid of all the machinery.
There's no DI/IoC in Rails, and it's a happy feeling.
界面
基本上,对于 ISession 的 Find、Last 和 FindBy 签名,您有几个界面明智的选项。
如果您想与动态参数名称保持相同的语法,First、Last 和 Find 都应该是 getter,并使用实现 bool TryInvoke(InvokeBinder binder, object[] args, out object result)的 DynamicObject 返回动态code> 将为您提供相同的
动态 Find(column:val, otherColum:otherVal)
语法。这是一个粗略的基本示例:如果您想要完全静态定义的方法,您只需执行 IDictionary 的单个参数或其他操作即可为您提供密钥对。
将调用转发到 Massive 动态方法
也有两种方法可以实现此目的。
最简单的方法是使用开源框架 ImpromptuInterface,它允许您以编程方式调用动态方法就像 c# 编译器 (包括动态命名参数)。
或者您可以尝试伪造进入
TryInvokeMember
的参数;The Interface
Basically you have a couple of options interface wise for the signature for your ISession's Find, Last and FindBy.
If you want to keep the same syntax with the dynamic argument names First, Last and Find should all be getters and return dynamic with a DynamicObject that Implements
bool TryInvoke(InvokeBinder binder, object[] args, out object result)
that will give you the samedynamic Find(column:val, otherColum:otherVal)
syntax. Here is a rough basic example:If you want completely statically defined methods you are just going to have to do a single parameter of IDictionary or something to give you the key pairs.
Forwarding the call to the Massive dynamic method
There are two ways to do this as well.
The easy way is to use the open source framework ImpromptuInterface that allows you to programmatically call dynamic methods just like the c# compiler (including dynamic named parameters).
Or you can just try to fake the parameters coming into the
TryInvokeMember
;