繁体   English   中英

如何抽象Entity Framework模型属性

[英]How to abstract Entity Framework model properties

我有一个看起来像这样的模型:

public class Task : ITask
{
    public int DocumentId { get; set; }
    public virtual Document Document { get; set; }
    public TaskType TaskType { get; }
    public string Value { get; }
}

现在,此类在DbSet中直接注册为DbContext 这意味着Document属性必须是具体类型。 我想让这段代码很容易测试,所以我希望将属性作为ITask接口所需的接口。 解决这个问题的一般方法是什么?

我想到的一种方法是将所有这些类放在一个单独的程序集中,但这似乎有点过时了。

编辑: ITask接口在不同的程序ITask定义,因此它不应该知道Document类型。

我只将EF模型用于数据访问层,并为业务层创建单独的模型。 数据访问层负责将EF模型映射到业务层模型并将其交给业务层。

然后,业务层模型也可以是不可变的,这可以具有优势。 此外,您可以要求所有属性在构造函数中为非null,然后您可以在整个业务层中依赖于此。

当然你可以说它几乎是编写代码的两倍。 这是真的,但IMO会产生更清晰的代码,因此这是我的首选方法。

接口可以在其中定义属性,因此您的ITask可以指定文档,如下所示:

public interface ITask {
    Document Document { get; set; }
}

但是你也说你想把Document属性作为一个接口,这就变得很棘手,因为你需要Task类中的具体类型。 通用接口在这里会有所帮助。

// The interfaces
public interface ITask<TDocument> where TDocument : IDocument, new() {
     TDocument Document { get; set; }
}

public interface IDocument {
    int Number { get; set; } // Example property
}


//The classes
public class Document : IDocument{
    public int Number { get; set; } // Example property
}

public class Task : ITask<Document> {
    public Document Document { get; set; }
}


// See if it works
public class Test {
    private Task myTask = new Task();

    public void TestMethod() {
        myTask.Document.Number = 1;
    }
}

请记住,在DBContext中使用具体类型。

至于接口应该位于何处,相同的装配或它们自己的位置,对此有很多观点。 就个人而言,我把它们放在远离实施类的自己的程序集中。 这个问题值得一读: 我应该有一个单独的接口程序集吗?

还有一个注释,类名称Task在.Net线程库中使用,因此可能值得考虑更改它以避免潜在的混淆。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM