gpt4 book ai didi

c# - Nest 无法使用 EF6/MVC5 处理大型数据库模型

转载 作者:行者123 更新时间:2023-11-30 12:26:31 25 4
gpt4 key购买 nike

我得到了一个数据库,应该可以对其进行基本的 CRUD 操作。这是通过使用 .NET 4.5/MVC5 和 EF6 快速完成的。这意味着数据库优先方法。

新要求:(弹性)搜索。

为自定义类(未链接到模型中的其他类)创建索引时,一切正常。当我使用一个有很多外键的类时,事情就停止了。该数据库由 100 个表组成,具有 400 多个外键。

我认为问题可能是循环引用(客户有 n 个契约(Contract),其中有一个对客户的引用,其中有一个契约(Contract)列表,......你明白了)。最终我遇到了 OutOfMemory 异常,一切都崩溃了。

代码:

public static Uri node;
public static ConnectionSettings settings;
public static ElasticClient client;

public ActionResult TestIndex()
{
node = new Uri("http://localhost:9200");
settings = new ConnectionSettings(node, defaultIndex: "crudapp");
client = new ElasticClient(settings);

var indexSettings = new IndexSettings();
indexSettings.NumberOfReplicas = 1;
indexSettings.NumberOfShards = 1;

//The next line causes the OutOfMemoryException
client.CreateIndex(c => c.Index("crudapp")
.InitializeUsing(indexSettings)
.AddMapping<Customer>(map => map.MapFromAttributes(maxRecursion: 1)));


foreach (Customer c in db.Customer.Where(a => a.Active == true))
client.Index(c);

return View("Index");
}

如何告诉 Nest 停止递归或不使用某些对象?

示例类:

    public partial class Customer
{
public Customer()
{
this.CustomerContract = new HashSet<CustomerContract>();
}

public int Customerid { get; set; }
public string CustomerName { get; set; }
public string Description { get; set; }
public bool Active { get; set; }

public virtual ICollection<CustomerContract> CustomerContract { get; set; }
}

public partial class CustomerContract
{
public CustomerContract()
{
this.Host = new HashSet<Host>();
}

public int CustomerContractid { get; set; }
public string CustomerContractName { get; set; }
public string Description { get; set; }
public int CustomerID { get; set; }
public bool Active { get; set; }

public virtual Customer Customer { get; set; }
public virtual ICollection<Host> Host { get; set; }
}

最佳答案

OutOfMemoryException 几乎可以肯定来自 Customer 对象的 JSON 序列化。因此,问题不是 NEST 或 Elasticsearch 功能之一,而是 JSON.NET 功能。

您可以通过以下两种方式之一处理此问题:

<强>1。有选择地序列化大对象

This article JSON.NET 的作者讨论了减小对象的大小。您可以为属性提供 JsonIgnoreAttribute property指示序列化程序忽略某些属性。或 IContractResolver 的实现可能对 EF 对象的定义影响较小(特别是考虑到它们是数据库优先生成的),但我不确定这是否可以与 JSON.NET 上的 NEST 依赖项结合使用。

如果您无法选择处理 NEST 对 JSON.NET 的依赖性,您总是可以找到另一种方法来序列化您的对象并通过使用 Elasticsearch.NET 语法而不是 NEST(本质上建立在-Elasticsearch.NET 的顶部)。因此,不是调用 ElasticClient.Index(..),而是调用 ElasticClient.Raw.Index(..),其中 body 参数是您希望索引的对象的 JSON 字符串表示(您自己构造的)。

<强>2。将大对象投影到较小的数据传输对象

不是索引Customer 对象,而是仅将您要索引的属性映射到以您的 Elasticsearch 架构/文档类型为目标的数据传输对象 (DTO)。

foreach (Customer c in db.Customer.Where(a => a.Active == true))
client.Index(new MyElasticsearchTypes.Customer()
{
CustomerId = c.CustomerId,
CustomerName = c.CustomerName,
Description = c.Description
});

在 C# 中,对于如何处理此类 DTO 的创建,您有很多选择,包括:

  1. 具有手动映射的显式类型对象(如我的示例)。
  2. 使用 AutoMapper 等映射工具明确类型化的对象.
  3. 动态对象。

扁平化设计

请注意,使用 Elasticsearch 并不是简单地将数据放入“索引”。您需要从“文档”的角度开始思考,并理解当您尝试为来自关系数据库的数据建立索引时的含义。 Elasticsearch 指南文章 Data In, Data Out是开始阅读的好地方。另一篇名为Managing relations inside Elasticsearch的文章与您的情况特别相关:

At it's heart, Elasticsearch is a flat hierarchy and trying to force relational data into it can be very challenging. Sometimes the best solution is to judiciously choose which data to denormalize, and where a second query to retrieve children is acceptable

关于c# - Nest 无法使用 EF6/MVC5 处理大型数据库模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28435610/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com