我想定制我的应用程序的实体,使他们有一个属性引用加载它们在DataContext。自定义的IQueryable <T>
我认为最好的办法就是以某种方式创建一个实现IQueryable的一类,并设置在其GetEnumerator方法实体DataContext属性。
我的问题是,我该如何使用使用LINQ的我在执行的IQueryable对于SQL,这样我就不必执行他们自己的供应商和表达?
BTW:对于我的情况下,有另一种方式?
下面的代码看看:
public partial class Product: IEntityBase
{
public Product()
{
_DataContext = new SampleDataContext();
}
private long _Id;
[Column(Storage="_Id", AutoSync=AutoSync.OnInsert, DbType="BigInt NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
public long Id
{
get{ return _Id; }
set{ _Id = value; }
}
private string _Name;
[Column(Storage="_Name", DbType="NVarChar(MAX) NOT NULL", CanBeNull=false
public string Name
{
get{ return _Name; }
set{ _Name = value; }
}
private SampleDataContext _DataContext;
//This is the property extending the Product class and should be set when this class is being returned
//by IQueryable<T>.GetEnumerator()
public SampleDataContext DataContext
{
get{ return _Name; }
set{ _Name = value; }
}
public MyQueryable<Product> GetProducts()
{
MyQueryable<Product> result = from p in context.Products
where {Some Conditions 1}
select p;
result.DataContext = _DataContext;
return result;
}
public void SomeMethod()
{
//This query will not actually set the DataCotnext property.
//And the generated sql query is something like:
//SELECT * FROM Products WHERE {Some Conditions 1} AND {Some Conditions 2}
var products = GetProducts().Where({Some Conditions 2});
//Now that the GetEnumerator() is called the DataContext property of the products
//will be set.
foreach(var item in products)
{
item.Name = "Test Name";
item.DataContext.SubmitChanges();
}
}
}
public MyQueryable<T>: IQueryable<T>
where T: class, IEntityBase
{
//
//Implementation of IQueryable which is my question
//
public IEnumerator<T> GetEnumerator()
{
foreach(var item in Provider.GetEnumerator<T>())
{
item.DataContext = this.DataContext;
yield return item;
}
}
public SampleDataContext DataContext{ get; set; }
}
public interface IEntityBase
{
SampleDataContext DataContext{ get; set; };
}
UPDATE
,我发现自己的答案。这里是示例代码来展示我是如何做到的。
public MyQueryable<T, TContext>: IQueryable<T>
where T: class, IEntityBase
where TContext: DataContext, new()
{
public MyQueryable<T>(TContext context, IQueryable<T> baseIQueryable)
{
if(baseIQueryable == null)
throw new ArgumentNullException("baseIQueryable");
this.Provider = baseIQueryable.Provider;
this.Expression = baseIQueryable.Expression;
this.DataContext = context;
}
public IEnumerator<T> GetEnumerator()
{
var enumerator = Provider.Execute<IEnumerable<T>>(Expression);
foreach(var item in enumerator)
{
item.DataContext = this.DataContext ?? new TContext();
yield return item;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
var enumerator = Provider.Execute<IEnumerable>(Expression);
foreach(var item in enumerator)
{
((IEntityBase<TContext>)item).DataContext = this.DataContext;
yield return item;
}
}
//
//Other implementations...
//
public SampleDataContext DataContext{ get; set; }
}
public partial class Product: IEntityBase
{
public MyQueryable<Product> GetProducts()
{
var result = from p in context.Products
where {Some Conditions 1}
select p;
return new MyQueryable<typeof(Product), DataContext>(this.DataContext, result);
}
}
看来,有没有办法设置属性不会破坏组合性。我对吗?如果是的话EF呢?我可以用EF做这个吗? – mrtaikandi 2009-01-28 11:49:23