0

我的应用程序中有一个非常简单的存储库模式,但现在我有一个异常情况,我需要返回 Code First 模型和一些额外的数据。见下文。

public IEnumerable<User> GetUsersWithinLocation(DbGeography geography)

我真正想在返回模型中包含的是用户实例和与地理位置的距离(以英里或其他单位)。

以下是我看到的选项:

选项1:我可以返回用户对象列表,没有距离,在前端重新计算第二次,避免弄乱我的数据模型,但似乎有点多余......而且,这在某些情况下可能是不可能的,并且我只是觉得这种做法是错误的。

选项 2:另一个选项是创建一个新的 DTO,该 DTO 由 User 组成或继承 User,例如 UserDistance 对象。这会给我我需要的一切,但我会为此创建一个新的存储库吗?如果每种模型类型返回的数据有很多变化,我可能会认为在大型应用程序中维护这有点不守规矩。

选项 3:实现某种动态的 ExtraData ViewBag 层,我可以在其中任意传入额外数据和 DTO。这将在我的层之间创建更紧密的耦合,因为必须知道名称。我也不是很喜欢这种方法。

非常感谢任何指导。

4

3 回答 3

1

以下是摆脱双重调用的方法Distance

public IDictionary<User, double?> GetUsersWithinByLocation(DbGeography geography)
{
    return this.Query.Select(x => new KeyValuePair<User, double?>(x, x.Address.Location.Distance(geography)))
                     .OrderBy(kvp => kvp.Value)
                     .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
}

你可以做的另一件事,我认为更好一点是改变你的返回类型,这样你就可以做一个更简单/更快的 LINQ 查询,这里是代码:

public IEnumerable<KeyValuePair<User, double?>> GetUsersWithinByLocation(DbGeography geography)
{
    return this.Query.Select(x => new KeyValuePair<User, double?>(x, x.Address.Location.Distance(geography)))
                     .OrderBy(kvp => kvp.Value);
}

您可以使用这种方法,也KeyValuePair<T1, T2>可以使用Tuple<T1, T2>.

请注意,在这两种情况下,我所做的都是首先“存储”计算,Distance然后通过子句中的Value属性访问它。KeyValuePair<T1, T2>OrderBy

希望这可以帮助 ;)

于 2013-03-10T08:04:57.153 回答
0

那这个呢?这里有什么问题吗?

public IDictionary<User, double?> GetUsersWithinByLocation(DbGeography geography)
{
    return this.Query.OrderBy(x=>x.Address.Location.Distance(geography))
          .ToDictionary(x => x, x => x.Address.Location.Distance(geography));
}

主要问题是我们运行这个距离函数两次,有没有办法解决这个问题?

于 2013-03-10T06:52:38.523 回答
0

我通常会问自己一个不同的问题:我可以使用域对象进行数据传输吗?几乎没有答案是肯定的。为什么会这样?在很多情况下,UI 会切入领域模型,并希望从中分得一杯羹。(几乎)总是涉及一个视图模型。大多数情况下,视图模型都是经过验证的。

所以对我来说:选项 2。但是存储库不应该提供视图模型。它应该是位于存储库和视图(控制器,如果您在 mvc 中)之间的服务层,它协调存储库调用以收集视图模型的数据。存储库在内部公开IQueryables,服务在这些 IQueryables 上编写查询并公开IEnumerables。

于 2013-03-10T10:48:03.143 回答