使用两个没有实现任何接口

时间:2017-10-24 12:25:07

标签: c# .net .net-core software-design

我正在开发一个使用ASP.NET Core 2.0和C#

的Angular应用程序

我的大多数控制器都有这种方法:

[HttpPost("[action]")]
public void Save([FromBody] List<Models.LinePresentation> lines)
{
    bool hasChanges = false;

    List<Models.LinePresentation> newLines = 
        lines
            .Where(l => l.LineId == 0)
            .ToList();

    if ((newLines != null) && (newLines.Count > 0))
    {
        hasChanges = true;

        foreach(Models.LinePresentation newLine in newLines)
        {
            Line newDbLine = new Line()
            {
                LineReferenceId = newLine.LineReferenceId,
                Name = newLine.Name
            };

            _context.Line.Add(newDbLine);
        }
    }

    List<Line> currentLines = _context.Line.ToList();

    foreach (Line dbLine in currentLines)
    {
        Models.LinePresentation modLine = 
            lines.FirstOrDefault(x => x.LineId == dbLine.LineId);

        if (modLine == null)
        {
            _context.Line.Remove(dbLine);

            if (!hasChanges)
                hasChanges = true;
        }
        else if ((dbLine.LineReferenceId != modLine.LineReferenceId) ||
                    (dbLine.Name != modLine.Name))
        {
            dbLine.LineReferenceId = modLine.LineReferenceId;
            dbLine.Name = modLine.Name;

            _context.Line.Update(dbLine);

            if (!hasChanges)
                hasChanges = true;
        }
    }

    if (hasChanges)
        _context.SaveChanges();
}

我可以更改类Models.LinePresentationLine,并将其与两个通用类一起使用。

而且我认为我可以使用像_context.Line那样的通用DbSet更改DbSet DbSet<T>(或者我错了)。

我的问题是,我必须将LineLinePresentation进行比较。就像我在代码中所做的那样:

else if ((dbLine.LineReferenceId != modLine.LineReferenceId) ||
         (dbLine.Name != modLine.Name))

这些课程是:

public class Line : IEquatable<Line>
{
    public int LineId { get; set; }
    public string Name { get; set; }
    public string LineReferenceId { get; set; }

    public ICollection<Batch> Batch { get; set; }
}

public class LinePresentation
{
    public int LineId { get; set; }
    public string Name { get; set; }
    public string LineReferenceId { get; set; }
}

有没有办法创建一个接口来比较这两个类?

我不这么认为,因为LineLinePresentation没有实现任何界面,我也不想使用反射。

2 个答案:

答案 0 :(得分:0)

如果您的LinePresentation是表示层实体而Line是业务域实体,那么直接比较它们并不是一个好习惯。您最好首先通过某些转换器将LinePresentation转换为Line,然后在域实体上实现比较器

尽管LineLinePresentation是非常相似的类,但根据我的经验,使它们实现某些通用接口非常方便 ILine因为它使分离层的整个想法变得无用(想法是从域和存储独立地改变表示不是吗?)。迟早你会想要改变你的演示文稿,如果不影响业务实体,你可能无法做到这一点,如果所有实现相同的接口,你可能无法做到这一点。

所以我建议你的代码看起来像

[HttpPost("[action]")]
public void Save([FromBody] List<Models.LinePresentation> lines)
{
    Save(lines.Select(l=>new Line {LineId = l.LineId, Name = l.Name, LineReferenceId = l.LineReferenceId}))
}

private void Save(IEnumerable<Line> lines)
{
    // Most of your code goes here slightly modified to work with business objects
}

稍后,方法Save(IEnumerable<Line>)可以提取到业务层逻辑,并可能在您的控制器中重复使用。

答案 1 :(得分:0)

如果你需要做的只是提供一个在相同属性意义上检查“相等”的方法,你可以使用扩展方法来做到这一点,这样你就不必修改任何一个类。

public static class LineExtensions
{
    public static bool Matches(this Line line, LinePresentation presentation)
    {
        return line.LineReferenceId == presentation.LineReferenceId
               && line.Name == presentation.Name;
    }
}

这在技术上与您现在所做的不同。它只是移动它,删除一些潜在的重复,并可能使它更具可读性,因为扩展方法的名称可以传达意图。

相关问题