首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在c#中将个人记录最佳匹配集合为组代表

在c#中将个人记录最佳匹配集合为组代表
EN

Stack Overflow用户
提问于 2015-08-05 19:56:31
回答 1查看 73关注 0票数 0

我们正在使用代码优先实体框架开发一个业务应用程序,我正在寻找解决以下问题的方法,如果可能的话,这个问题不会出现在数据库之外。

我们有一个类似于以下内容的持久性模型:

代码语言:javascript
复制
public abstract class DataCode
{
   public long Id { get; set; }
   public string Code { get; set; }
   public string Description { get; set; }
}

public class Option : DataCode
{
   // a bunch of stuff that describes an Option
}

public class Model : DataCode
{
   // a bunch of stuff that describes a product model
}

public class Version
{
   public long Id { get; set; }
   // a bunch of stuff that describes a version of the product model
}

public class ModelOptionVersion
{
   public Model ThisModel { get; set; }
   public Option WithThisOption { get; set; }
   public Version UsingThisVersion { get; set; }
   // a bunch of stuff that is important to track 
   // at the intersection of these three properties
}

除了用户希望使用“家庭代码”和“公共代码”来应用属性值之外,所有这些代码都工作得很好。为了支持这一点,我认为以下课程将有效:

代码语言:javascript
复制
public abstract class CodeGroup
{
   public virtual ICollection<DataCode> DataCodes { get; set; }
}

public class Family : CodeGroup, DataCode
{
   public Family(ICollection<Model> Models)
   {
      base:DataCodes = Models;
   }
}

public class CommonCode : CodeGroup, DataCode
{
   public Family(ICollection<Option> Options)
   {
      base:DataCodes = Options;
   }
}

这对于将FamilyCodeCommonCode以及一些逻辑扩展到单独的ModelOptionVersion记录(foreach Model in Family...)是很好的,也是很好的。然而,阻碍我的是如何将一组ModelOptionVersion记录最好地匹配到FamilyCodeCommonCode代表中。

如果这是福特(它不是),数据可能如下所示:

代码语言:javascript
复制
Family    | Model
Trucks    | F-150
Trucks    | F-250
Trucks    | F-350
SuperDuty | F-250
SuperDuty | F-350

CommonCode     | Option
Gas Engines    | 4.6l V-8 Gas
Gas Engines    | 5.4l V-8 Gas
Diesel Engines | 6.4l V-8 Diesel
Diesel Engines | 7.3l V-8 Diesel
Diesel Engines | 6.0l V-8 Diesel

Model | Option          | Version
F-150 | 4.6l V-8 Gas    | 2015
F-150 | 4.6l V-8 Gas    | 2016
F-150 | 5.4l V-8 Gas    | 2015
F-150 | 5.4l V-8 Gas    | 2016
F-250 | 5.4l V-8 Gas    | 2015
F-250 | 5.4l V-8 Gas    | 2016
F-350 | 5.4l V-8 Gas    | 2015
F-350 | 5.4l V-8 Gas    | 2016
F-250 | 6.4l V-8 Diesel | 2015
F-250 | 6.4l V-8 Diesel | 2016
F-350 | 6.4l V-8 Diesel | 2015
F-350 | 6.4l V-8 Diesel | 2016

用户希望根据“超级柴油发动机”或"2016卡车加燃气发动机“对商品进行定价。当他们创造价格记录时,他们不仅希望看到这一点,而且当他们回头再看的时候。因此,我需要一种方法,不仅扩展FamilyCodeDataCode成员,而且将它们卷起来。但从数据中不一定清楚数据的来源是什么。而且,系统应该足够聪明,当有人说“这只在F-250和F-350上可用”时,系统会说“使用SuperDuty”。

在我看来,我需要某种最好的解决方案,也许是一些轻量级的模糊逻辑。是否存在用于此的.NET库?我必须从头开始做吗?我怎样才能做到这一点?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-08-05 21:43:38

然而,阻碍我的是如何将一组ModelOptionVersion记录最好地匹配到FamilyCode或CommonCode代表中。

您在这里要做的是找到FamilyCodes (或CommonCodes),以便某个集合中的每个ModelOptionVersion都有一个由该FamilyCode指定的模型。

代码语言:javascript
复制
var desiredModels = // some collection of Models

var familyCodesByFamily = (
    from familyCode in db.FamilyCodes
    group familyCode by familyCode.Family into family
    select family);

var applicableFamilies = (
    from family in familyCodesByFamily
    where desiredModels.All(dm => family.Any(f=> f.Model == dm))
    select family.Key).ToList();

我还没有测量这种查询的性能,但它并不能很直接地映射到SQL能做什么。SQL并不直接允许您执行通用量词(“给我x,y"),但它允许您做存在量词(”给我x,这样就有y")和否定。如果发现上述方法效果不佳,则在语义上应该等效的另一种公式是:

代码语言:javascript
复制
var incorrectFamilies = 
    (from familyCode in db.FamilyCodes
    where !desiredModels.Contains(familyCode.Model)
    select familyCode.Family).Distinct();

var correctFamilies =
    (from familyCode in db.FamilyCodes
    where !incorrectFamilies.Contains(familyCode.Model)
    select familyCode.Family).Distinct().ToList();

它们生成不同的SQL,自然的第一个选项比第二个选项提供了更复杂的SQL。无论您选择哪种样式,CommonCode的代码都应该遵循相同的模板。

编辑:对于真正的模糊匹配,让我们为一组模型和一组家庭之间的匹配程度开发两个度量。第一个(也是更重要的)措施,我们将称为“覆盖”,这涉及到多少型号包括在家庭。第二个我们称之为"fit",它涉及到在模型集中包含了多少个家庭成员(如果您有两个家族,这两个家族都完全包含所需的模型,我们希望在我们所期望的集合之外有更少的额外模型)。我们将根据比赛的优劣来排序结果,然后取我们能处理的结果的数量。

代码语言:javascript
复制
var fuzzyFamilies = (
    from family in familyCodesByFamily
    let coverage = desiredModels.Average(dm => family.Any(f => f.Model == dm) ? 1.0 : 0.0)
    let fit = family.Average(f => desiredModels.Contains(f.Model) ? 1.0 : 0.0)
    orderby coverage descending, fit descending
    select family.Key)
    .Take(resultCount)
    .ToList();
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31841715

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档