2

当我使用两个不同的生成的 linq 代码时,如何实现 Rob Conery 在 [MVC Storefront][1] 中显示的所谓“存储库模式”?我是否需要实现一个真正的存储库模式,正如 Fredrik Normen 在存储库模式有什么目的中所讨论的那样?? 问题是我想从我的“存储库”传递一些 LINQ 提供的不错的特性,以便我以后可以使用它,所以如果不需要,我不想像 Fredrik 讨论的那样实现真正的存储库模式。

现在到我的问题。我已经下载了 [dblinq][3],它是 MySql、Oracle 和 PostgreSQL 的 Linq 提供程序。在我的项目中,我现在已经为 MySQL 和 SQL(microsoft) 生成了 LINQ 代码。问题是它们都需要生成具有相同名称但内容有所不同的类。我可以使用命名空间或其他东西以某种方式实现它,以便我可以同时使用它们,就像“存储库模式”的想法一样?语言表 SQl 的示例

[Table(Name="dbo.Language")]
public partial class Language : INotifyPropertyChanging, INotifyPropertyChanged
{

    private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);

    private int _Id;

    private string _Name;

    private EntitySet<Book> _Books;

#region Extensibility Method Definitions
partial void OnLoaded();
partial void OnValidate(System.Data.Linq.ChangeAction action);
partial void OnCreated();
partial void OnIdChanging(int value);
partial void OnIdChanged();
partial void OnNameChanging(string value);
partial void OnNameChanged();
#endregion

    public Language()
    {
        this._Books = new EntitySet<Book>(new Action<Book>(this.attach_Books), new Action<Book>(this.detach_Books));
        OnCreated();
    }

    [Column(Storage="_Id", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
    public int Id
    {
        get
        {
            return this._Id;
        }
        set
        {
            if ((this._Id != value))
            {
                this.OnIdChanging(value);
                this.SendPropertyChanging();
                this._Id = value;
                this.SendPropertyChanged("Id");
                this.OnIdChanged();
            }
        }
    }

    [Column(Storage="_Name", DbType="NVarChar(100) NOT NULL", CanBeNull=false)]
    public string Name
    {
        get
        {
            return this._Name;
        }
        set
        {
            if ((this._Name != value))
            {
                this.OnNameChanging(value);
                this.SendPropertyChanging();
                this._Name = value;
                this.SendPropertyChanged("Name");
                this.OnNameChanged();
            }
        }
    }

    [Association(Name="Language_Book", Storage="_Books", ThisKey="Id", OtherKey="Language")]
    public EntitySet<Book> Books
    {
        get
        {
            return this._Books;
        }
        set
        {
            this._Books.Assign(value);
        }
    }

    public event PropertyChangingEventHandler PropertyChanging;

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void SendPropertyChanging()
    {
        if ((this.PropertyChanging != null))
        {
            this.PropertyChanging(this, emptyChangingEventArgs);
        }
    }

    protected virtual void SendPropertyChanged(String propertyName)
    {
        if ((this.PropertyChanged != null))
        {
            this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    private void attach_Books(Book entity)
    {
        this.SendPropertyChanging();
        entity.Language1 = this;
    }

    private void detach_Books(Book entity)
    {
        this.SendPropertyChanging();
        entity.Language1 = null;
    }
}

MySQL

    [Table(Name = "asp.Language")]
public partial class Language : INotifyPropertyChanged
{
    #region INotifyPropertyChanged handling

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    #endregion

    #region int ID

    private int _id;
    [DebuggerNonUserCode]
    [Column(Storage = "_id", Name = "Id", DbType = "int", IsPrimaryKey = true, IsDbGenerated = true, CanBeNull = false)]
    public int ID
    {
        get
        {
            return _id;
        }
        set
        {
            if (value != _id)
            {
                _id = value;
                OnPropertyChanged("ID");
            }
        }
    }

    #endregion

    #region string Name

    private string _name;
    [DebuggerNonUserCode]
    [Column(Storage = "_name", Name = "Name", DbType = "varchar(100)", CanBeNull = false)]
    public string Name
    {
        get
        {
            return _name;
        }
        set
        {
            if (value != _name)
            {
                _name = value;
                OnPropertyChanged("Name");
            }
        }
    }

    #endregion

    #region Children

    private EntitySet<Book> _book;
    [Association(Storage = "_book", OtherKey = "Language", ThisKey = "ID", Name = "Book_ibfk_1")]
    [DebuggerNonUserCode]
    public EntitySet<Book> Book
    {
        get
        {
            return _book;
        }
        set
        {
            _book = value;
        }
    }


    #endregion

    #region Attachement handlers

    private void Book_Attach(Book entity)
    {
        entity.LanguageLanguage = this;
    }

    private void Book_Detach(Book entity)
    {
        entity.LanguageLanguage = null;
    }


    #endregion

    #region ctor

    public Language()
    {
        _book = new EntitySet<Book>(Book_Attach, Book_Detach);
    }

    #endregion

}
4

4 回答 4

1

这有点离题,但它可能会有所帮助。

如果您正在使用 Linq、存储库、MySql 和 MS Sql,以及 Rob Connery 的建议,您不妨使用 SubSonic 3,让您的生活更轻松一些。

这是一个 5 分钟的演示:http ://subsonicproject.com/docs/Simple_Repo_5_Minute_Demo

于 2009-07-23T00:31:22.030 回答
1

理想情况下,每个类只创建一次,数据库差异应该由 ORM 处理(这就是 NHibernate 和 Subsonic 的工作方式)。

如果您确实需要为每个数据库使用不同的类,那么可以,只要它们位于不同的命名空间中,您就可以拥有同名的类。如果您自己编写类的代码,这很容易:

// C# sample
namespace MyCompany.MyApp.Entities.Oracle
{
    public class MyClass
    {
    // ...
    }
}

namespace MyCompany.MyApp.Entities.SqlServer
{
    public class MyClass
    {
    // ...
    }
}

如果类是自动生成的,您应该在代码生成工具中检查如何指定命名空间。例如,使用 LINQ to SQL 设计器,您可以在表/类属性中指定命名空间,或者自己编辑 DBML 文件。

于 2009-08-27T17:18:56.257 回答
0

我和你的情况一样,我用的是Linq-to-SQL,但是以后我想试试Entity Framework,我会的。

对于我所看到的,解决方案是使用依赖注入和一个 ioc 容器(如果你不使用它,请看一下,可能看起来很难,但非常简单和有趣)。

大多数示例为每个存储库创建一个接口,然后使用 ioc 配置文件,您可以选择要使用的内容。

例如,您有一个ICustomersRepository,这就是您可能在控制器中使用的东西,以及一个SQLCustomersRepository和一个EntityCustomersRepository,您只能交换配置文件。

正如您所说,问题是具有相同名称的实体......解决方案是为实体使用相同的模式,为每个实体创建一个接口并使用 ioc 容器。我知道这很乏味,我要做的是创建一个 T4 模板,自动为每个实体创建接口,然后替换 T4 模板,使用 LinqToSQL 和 entiy 框架来实现它......是的,工作量很大。

有关 T4 的介绍,请观看此视频, http: //msdn.microsoft.com/en-us/vstudio/cc308634.aspx

于 2009-08-03T12:48:06.487 回答
0

我会为您的 BO 建议一个实体命名空间,例如 MyCompany.MyApp.Entities。

然后,您可以更改每个 DBML 的实体命名空间属性以在其中生成您的实体。如果您对相同类型使用多个 DBML,则需要为每个 DBML 设置一个单独的命名空间,例如 MyCompany.MyApp.Entities.MySql)

如果您需要预先为不止一种类型的数据库/数据访问平台提供类,我建议您创建您的实体可以具体化的抽象基类,以及一个抽象存储库来进行数据访问。

根据我自己的经验,我最近创建了一个抽象的 LinqToSqlRepostory,然后为我的主要业务对象扩展了它。

于 2009-08-04T12:03:44.447 回答