1

とにかく、Linq to Sql 生成エンティティにプロパティを追加して、その DataContext を参照する簡単な方法はありますか? 例えば:

var myContext = new DataContext(); 
var product = context.Products.Where(p => p.Id == productId).SingleOrDefault(); 

製品エンティティには、myContext、datacontext への参照を持つ「Context」(product.Context) というプロパティがあります。

生成されたエンティティをカスタマイズする方法を知っています。私の質問は、作成する各インスタンスの「コンテキスト」プロパティをそれ自体に設定するようにカスタマイズする方法です(DataContextだと思います)。

自分が正しいことをしているかどうかはわかりません。より少ないコードで最高のパフォーマンスを発揮するビジネス カプセル化モデルを作成したいと考えています。グーグルで検索したところ、DataContext オブジェクトが非常に軽量であることがわかりました。そのため、DataContext のインスタンスを各オブジェクトに追加するのは良い方法だと思いました。これにより、オブジェクトを更新または削除するたびに、データコンテキストの新しいインスタンスにオブジェクトを再度アタッチしたり切り離したりする必要がなくなります。

他の解決策があれば、本当に感謝します。

ありがとう

4

6 に答える 6

2

プロパティを Linq to Sql 生成エンティティに追加して、その DataContext を参照する簡単な方法はありますか?

これを実現する簡単な方法はありません。

于 2009-01-13T17:56:54.217 に答える
1

ここを参照してください: Linq to Sql クエリのソース DataContext を決定する

私は多かれ少なかれ同じ質問をしました。linq to sql クエリが返す IQueryable からコンテキストを取得できますが、私の知る限り、エンティティ自体からは取得できません。

于 2009-01-13T19:36:37.167 に答える
1

これを行うと、LINQ-to-SQL の目的の一部が無効になります。目的の 1 つは、データベースの考慮事項に基づいて設計を変更する必要がなく、所有しているオブジェクトを操作できるようにすることです。

DataContext をデータベースにアタッチすると、コード内の表現とそれを永続化する手段が結合されますが、これは通常、設計上の考えとしては不適切です。

ただし、これを行う必要があると思われる場合は、いつでもクラスから派生させてから、DataContext を公開するそのクラスにインターフェイスを実装できます。

基本クラスを LINQ-to-SQL デザイナーに示すことはできず、すべてのエンティティで共有実装を使用できるようにする必要があるため、インターフェイスを実装することをお勧めします。

于 2009-01-13T18:02:27.000 に答える
0

実際、私はcasperOneに同意します。本当にこれが必要な場合は、linq-to-sqlが生成するクラスが部分的であることを思い出しました。したがって、必要な任意のクラスに部分クラスを記述し、それに拡張機能を追加できます。

于 2009-01-13T19:17:33.773 に答える
0

データ コンテキストを ref パラメーターとして、部分 Product オブジェクトのカスタム メソッドに渡します。

public partial class Product 
{
    public string GetSomethingElse(ref DataContext dbase) 
    {
         return dbase.OtherTableWhatever.Count.ToString(); // whatever
    }
}

aspx.cs 内:

var context = new DataContext();
var product = context.Products.SingleOrDefault(x => x.id == 1);
var s = product.GetSomethingElse(ref context);
于 2011-03-09T14:51:42.973 に答える
0

System.Data.Linq 用に作成したカスタム ラッパーを次に示します。これには find メソッドが含まれているため、コードの代わりに:

var myContext = new DataContext(); 
var product = context.Products.Where(p => p.Id == productId).SingleOrDefault();

あなたはこれを行うことができます

var myContext = new DataContext(); 
var product = context.Products.Find(productId); //(assuming productId is your primary key)

以下のコードを取得して、product.Context を設定するカスタム変更を行うことができますが、これは DataContext を変更する例です。

save メソッドと delete メソッドも作成しました。レコードが渡されているにもかかわらず、レコードを再取得することに気付くでしょう。これを行うのは、レコードがコンテキストから切り離されて更新されない可能性があるためです。完全なコードが必要な場合は、github リンクを投稿できます。

public abstract class DbContext : IDisposable
{
    #region Properties
    private string _connectionString { get; set; }
    private DataContext _context { get; set; }
    #endregion

    #region Constructor
    public DbContext(string connectionString)
    {
        _connectionString = connectionString;
        _context = new DataContext(_connectionString);
        Initialized(_context);
    }

    public DbContext(string server, string database, string userID, string password)
    {
        _connectionString = string.Format(
        "Server={0};Database={1};User Id={2};Password={3};MultipleActiveResultSets=true",
        server,
        database,
        userID,
        password);

        _context = new DataContext(_connectionString);
        Initialized(_context);
    }
    #endregion

    #region Methods
    /// <summary>
    /// Is used to get the contents of a Sql Server Table.
    /// </summary>
    /// <typeparam name="TEntity">Type</typeparam>
    /// <returns>Table</returns>
    public Table<TEntity> GetTable<TEntity, TPKType>()
        where TEntity : DbTableEquatable<IDbTableEquatable<TPKType>>
        where TPKType : struct
    {
        return _context.GetTable<TEntity>();
    }

    /// <summary>
    /// Is used to get the contents of a Sql Server Table.
    /// </summary>
    /// <typeparam name="TEntity">Type</typeparam>
    /// <returns>Table</returns>
    public Table<TEntity> GetTable<TEntity>()
        where TEntity : DbTableEquatable<IDbTableEquatable<long>>
    {
        return GetTable<TEntity, long>();
    }

    protected virtual void Initialized(DataContext context) { }

    /// <summary>
    /// Saves the changes to the database.  In order to save the table must inherit from DbTableEquatable 
    /// and be a type of IDbTableEquatable and the Primary Key Type must be a C# Structure
    /// </summary>
    /// <typeparam name="TEntity">Record Type</typeparam>
    /// <typeparam name="TPKType">Primary Key Type</typeparam>
    /// <param name="entity">Record</param>
    public virtual void SaveChanges<TEntity, TPKType>(TEntity entity)
        where TEntity : DbTableEquatable<IDbTableEquatable<TPKType>>
        where TPKType : struct
    {
        var changedList = _context.GetTable<TEntity>();
        var ID = entity.GetType().GetProperty("ID").GetValue(entity);

        _preprocessSave<TEntity, TPKType>(entity);

        // Save changes
        if (Convert.ToInt64(ID) == 0)
        {
            // Insert
            // If No ID we need to insert on submit
            _context.GetTable<TEntity>().InsertOnSubmit((TEntity)entity);
            _context.SubmitChanges();
        }
        else
        {
            // Update
            var item = changedList.Where(w => w.Equals(entity)).FirstOrDefault();
            ReflectionManager.SetValuesWithSkip(entity, item, "ID");
            _context.SubmitChanges();
        }

        Refresh();
    }

    /// <summary>
    /// Saves the changes to the database.  In order to save the Table the Record is from must inherit from DbTableEquatable 
    /// and be a type of IDbTableEquatable and the Primary Key Type must be a C# Structure
    /// </summary>
    /// <typeparam name="TEntity">Record Type</typeparam>
    /// <param name="entity">Record</param>
    public virtual void SaveChanges<TEntity>(TEntity entity)
        where TEntity : DbTableEquatable<IDbTableEquatable<long>>
    {
        SaveChanges<TEntity, long>(entity);
    }

    /// <summary>
    /// Saves any non committed changes to the database
    /// </summary>
    public void SaveChanges()
    {
        _context.SubmitChanges();
        Refresh();
    }

    /// <summary>
    /// Marks the record as delete and will be deleted when saved
    /// </summary>
    /// <typeparam name="TEntity">Record Type</typeparam>
    /// <typeparam name="TPKType">Primary Key Type</typeparam>
    /// <param name="entity">Record</param>
    public virtual void DeleteOnSave<TEntity, TPKType>(TEntity entity)
        where TEntity : DbTableEquatable<IDbTableEquatable<TPKType>>
        where TPKType : struct
    {
        var item = _context.GetTable<TEntity>().Where(w => w.Equals(entity)).FirstOrDefault();
        _context.GetTable<TEntity>().DeleteOnSubmit((TEntity)item);
    }

    /// <summary>
    /// Marks the record as delete and will be deleted when saved
    /// </summary>
    /// <typeparam name="TEntity">Record Type</typeparam>
    /// <param name="entity">Record</param>
    public virtual void DeleteOnSave<TEntity>(TEntity entity)
        where TEntity : DbTableEquatable<IDbTableEquatable<long>>
    {
        DeleteOnSave<TEntity, long>(entity);
    }

    protected virtual void _preprocessSave<TEntity, TPKType>(TEntity entity)
        where TEntity : DbTableEquatable<IDbTableEquatable<TPKType>>
        where TPKType : struct
    {

    }

    protected virtual void _preprocessSave<TEntity>(TEntity entity)
        where TEntity : DbTableEquatable<IDbTableEquatable<long>>
    {
        _preprocessSave<TEntity, long>(entity);
    }

    public void Dispose()
    {
        _connectionString = "";
        _context.Dispose();
        _context = null;
    }

    public virtual void Refresh<TEntity>(RefreshMode mode, TEntity entity) where TEntity : class
    {
        _context.Refresh(RefreshMode.OverwriteCurrentValues, entity);
    }

    public virtual void Refresh()
    {
        _context = new DataContext(_connectionString);
    }

    public virtual void Refresh<TEntity>(RefreshMode mode, params TEntity[] entities) where TEntity : class
    {
        _context.Refresh(RefreshMode.OverwriteCurrentValues, entities);
    }

    public virtual void Refresh<TEntity>(RefreshMode mode, IEnumerable<TEntity> entities) where TEntity : class
    {
        _context.Refresh(RefreshMode.OverwriteCurrentValues, entities);
    }
    #endregion
}

拡張機能

public static class Extension
{
    public static TEntity Find<TEntity, TPKType>(this Table<TEntity> table, TPKType ID, string pkName = "ID")
        where TEntity : DbTableEquatable<IDbTableEquatable<TPKType>>
        where TPKType : struct
    {
        TEntity copy = Activator.CreateInstance<TEntity>();

        // set value through reflection
        copy.GetType().GetProperty(pkName).SetValue(copy, ID, null);
        return (TEntity)table.Where(w => w.Equals(copy)).FirstOrDefault();
    }

    public static TEntity Find<TEntity>(this Table<TEntity> table, long ID, string pkName = "ID")
        where TEntity : DbTableEquatable<IDbTableEquatable<long>>
    {
        TEntity copy = Activator.CreateInstance<TEntity>();

        // set value through reflection
        copy.GetType().GetProperty(pkName).SetValue(copy, ID, null);
        return (TEntity)table.Where(w => w.Equals(copy)).FirstOrDefault();
    }
}

}

インターフェイス/抽象化

/// <summary>
/// This Class Assumes the type T has a property called ID. MUST be 
/// used with IDbEquatable
/// </summary>
/// <typeparam name="T">Class Type</typeparam>
public abstract class DbTableEquatable<T> : IEquatable<T> where T : class
{
    public bool Equals(T other)
    {
        //Check whether the compared object is null.  
        if (Object.ReferenceEquals(other, null))
        {
            return false;
        }

        //Check whether the compared object references the same data.  
        if (Object.ReferenceEquals(this, other))
        {
            return true;
        }

        return ((dynamic)other).ID == ((dynamic)this).ID;
    }
}

/// <summary>
/// Needs to be inherited from in order for Ion.Data.Linq functions to work
/// </summary>
/// <typeparam name="T">Primary Key Type</typeparam>
public interface IDbTableEquatable<T>
{
    T ID { get; set; }
}

ここにテーブルの実装があります

[Table(Name = "Crews")]
public class Crew : DbTableEquatable<IDbTableEquatable<long>>, IDbTableEquatable<long>
{
    [Column(IsPrimaryKey = true, DbType = "Bigint NOT NULL IDENTITY", AutoSync = AutoSync.OnInsert, IsDbGenerated = true)]
    public long ID { get; set; }
    [Column]
    public string Alias { get; set; }
    [Column]
    public string DefaultForeground { get; set; }
    [Column]
    public string DefaultBackground { get; set; }
    [Column]
    public string AccountEmailAddress { get; set; }
    [Column]
    public long? CrewLeaderEmployeeID { get; set; }
    [Column]
    public string Comments { get; set; }
    [Column]
    public string Password { get; set; }
    [Column]
    public string PrivateICSLink { get; set; }
    [Column]
    public string PrivateXMLLink { get; set; }
}
于 2014-08-06T19:52:12.450 に答える