简体   繁体   English

如何制作通用存储库?

[英]How to make a Generic Repository?

I am wondering if anyone has any good tutorials(or maybe even a library that is already made and well documented) on making a generic repository. 我想知道是否有人在制作通用存储库时有任何好的教程(或者甚至可能是已经制作并且记录良好的库)。

I am using currently linq to sql but it might change so I don't know if you can make a generic repository that would take little to no changes if I would say switch to entity framework. 我正在使用linq到sql,但它可能会改变所以我不知道你是否可以创建一个通用的存储库,如果我说切换到实体框架,几乎没有任何变化。

Thanks 谢谢

I think I should also add why I want a generic repository. 我想我还应该添加为什么我想要一个通用的存储库。 The reason is in my database I have like corporate tables(users who's subscriptions are paid by someone else) and individual tables(people who find my site through google or whatever and pay for their own subscription) 原因是在我的数据库中我喜欢公司表(订阅的用户是由其他人支付的)和个人表(通过谷歌或其他任何人找到我的网站并为自己的订阅付费的人)

But I will have 2 very similar tables. 但我会有两张非常相似的牌桌。 For instance I have 2 settings tables one for corporate users and one for the individuals. 例如,我有2个设置表,一个用于企业用户,一个用于个人。

Now since they are 2 different tables I need 2 different insert methods as I am inserting it into 2 different tables and at this current time only one field is different(that is the PK). 现在因为它们是2个不同的表,我需要2种不同的插入方法,因为我将它插入2个不同的表中,并且在当前时间只有一个字段是不同的(即PK)。

So now I need all these duplicate methods and I don't want that. 所以现在我需要所有这些重复的方法,我不希望这样。 Maybe what I have in my database is could be considered as a design flaw(and maybe it is) but one of the reasons behind this was if needed I can break up my database into 2 different databases very easy and I am not going to change my design anytime soon. 也许我在我的数据库中所拥有的可能被认为是一个设计缺陷(也许是)但这背后的原因之一是如果需要我可以很容易地将我的数据库拆分成2个不同的数据库而且我不会改变我的设计很快就会出现。

Here is my answer to another question of the same type. 这是我对同一类型的另一个问题的回答。 Hope it helps: 希望能帮助到你:

Advantage of creating a generic repository vs. specific repository for each object? 为每个对象创建通用存储库与特定存储库的优势?

Edit: 编辑:

It sounds like you want to treat two concrete types as one logical type. 听起来你想将两种具体类型视为一种逻辑类型。 To do that, first define the logical type: 为此,首先定义逻辑类型:

public interface ISubscription
{
    // ...
}

Then, define the concrete types as part of your data model (interfaces would be implemented in another partial class): 然后,将具体类型定义为数据模型的一部分(接口将在另一个分部类中实现):

[Table("CorporateSubscription")]
public partial class CorporateSubscription : ISubscription
{

}

[Table("IndividualSubscription")]
public partial class IndividualSubscription : ISubscription
{

}

Next, define the repository which operates on the logical type: 接下来,定义对逻辑类型进行操作的存储库:

public interface ISubscriptionRepository
{
    CorporateSubscription GetCorporate(string key);

    IndividualSubscription GetIndividual(int userId);

    IEnumerable<ISubscription> ListAll();

    IEnumerable<CorporateSubscription> ListCorporate();

    IEnumerable<IndividualSubscription> ListIndividual();

    void Insert(ISubscription subscription);
}

Finally, implement the interface by using both tables: 最后,使用两个表实现接口:

public class SubscriptionRepository : ISubscriptionRepository
{
    private readonly YourDataContext _dataContext;

    public SubscriptionRepository(YourDataContext dataContext)
    {
        _dataContext = dataContext;
    }

    #region ISubscriptionRepository

    public CorporateSubscription GetCorporate(string key)
    {
        return _dataContext.CorporateSubscriptions.Where(c => c.Key == key).FirstOrDefault();
    }

    public IndividualSubscription GetIndividual(int userId)
    {
        return _dataContext.IndividualSubscriptions.Where(i => i.UserId == userId).FirstOrDefault();
    }

    public IEnumerable<ISubscription> ListAll()
    {
        return ListCorporate()
            .Cast<ISubscription>()
            .Concat(ListIndividual().Cast<ISubscription>());
    }

    public IEnumerable<CorporateSubscription> ListCorporate()
    {
        return _dataContext.CorporateSubscriptions;
    }

    public IEnumerable<IndividualSubscription> ListIndividual()
    {
        return _dataContext.IndividualSubscriptions;
    }

    public void Insert(ISubscription subscription)
    {
        if(subscription is CorporateSubscription)
        {
            _dataContext.CorporateSubscriptions.InsertOnCommit((CorporateSubscription) subscription);
        }
        else if(subscription is IndividualSubscription)
        {
            _dataContext.IndividualSubscriptions.InsertOnCommit((IndividualSubscription) subscription);
        }
        else
        {
            // Forgive me, Liskov
            throw new ArgumentException(
                "Only corporate and individual subscriptions are supported",
                "subscription");
        }
    }
    #endregion
}

Here is an example of an insert. 这是一个插入的例子。 Don't get too wrapped up in the presenter class; 不要在演讲者课上过于紧张; I just needed a situation in which subscriptions would be created based on a flag: 我只需要一种基于标志创建订阅的情况:

public class CreateSubscriptionPresenter
{
    private readonly ICreateSubscriptionView _view;
    private readonly ISubscriptionRepository _subscriptions;

    public CreateSubscriptionPresenter(
        ICreateSubscriptionView view,
        ISubscriptionRepository subscriptions)
    {
        _view = view;
        _subscriptions = subscriptions;
    }

    public void Submit()
    {
        ISubscription subscription;

        if(_view.IsCorporate)
        {
            subscription = new CorporateSubscription();
        }
        else
        {
            subscription = new IndividualSubscription();
        }

        subscription.Notes = _view.Notes;

        _subscriptions.Insert(subscription);
    }
}

Great Linq to Sql resources: Great Linq to Sql资源:

A t4 template that by generates exactly what is created by default, but can be fully customised. 一个t4模板,它通过生成默认创建的内容,但可以完全自定义。

http://l2st4.codeplex.com/ http://l2st4.codeplex.com/

Using Linq to Sql for a multi tier application. 使用Linq to Sql进行多层应用程序。 It has a GenericObjectDataSource which I have found very handy 它有一个GenericObjectDataSource,我发现它非常方便

http://multitierlinqtosql.codeplex.com http://multitierlinqtosql.codeplex.com

Search all properties of an IQueryable with one single search 只需一次搜索即可搜索IQueryable的所有属性

http://naspinski.codeplex.com/ http://naspinski.codeplex.com/

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

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