Я пытаюсь написать какой-нибудь универсальный linqtoSQL, который выполняет операции над объектами на основе их первичных ключей. Некоторые сущности, с которыми я работаю, имеют составные первичные ключи.
По сути, я хочу иметь возможность делать такие вещи, как:
if( PrimaryKey(foo) == PrimaryKey(bar) ) ...
или
from oldEntity in oldTableOrCollection
join newEntity in newTableOrCollection
on PrimaryKeyOf(oldEntity) equals PrimaryKeyOf(newEntity)
select new {oldEntity, newEntity}
только с требованием, чтобы у сущностей были первичные ключи.
Вот что я нашел до сих пор:
Можно делать такие вещи, как
var query = from row in oneTableOfRows
join otherRow in anotherTableOfRows on
new { row.Column1, row.Column2 }
equals
new { otherRow.Column1, otherRow.Column2}
select ...;
, в котором linqtosql будет использовать анонимные типы для сравнения (при условии совпадения имен свойств).
Затем я могу абстрагировать метод выбора столбцов, к которым нужно присоединиться, чтобы разрешить общие типы строк:
void DoQuery<RowType,KeyType>(Table<RowType> oneTableOfRows,
Table<RowType> anotherTableOfRows,
Func<RowType, KeyType> keySelector)
{
var query = from row in oneTableOfRow
join otherRow in anotherTableOfRows on
keySelector(row)
equals
keySelector(otherRow)
select ...;
}
...
Func<rowType, keyType> myKeySelector = row => new { row.Column1, row.Column2 };
DoQuery(table, otherTable, myKeySelector);
Сейчас я пытаюсь перейти к тому, где keySelector выберет первичный ключ любого RowType. Я использую пользовательский шаблон на основе http://www.codeplex.com/l2st4 для создания моих сущностей (что само по себе довольно похоже на значение по умолчанию в VS).
Я надеюсь в идеале дать каждому сгенерированному RowType возможность выбрать свой первичный ключ, полученный из dbml. Пока выход выглядит следующим образом:
public interface IPrimaryKeyEntity<PrimaryKeyType>
{
PrimaryKeyType PrimaryKey { get; }
}
//Here, Product is a table with composite primary key based on its ProductID and it's ProductPriceVersionID columns
//I've tried using both class and struct as the primary key type for entities
public class ProductPrimaryKey
{
public Guid ProductID;
public Guid ProductPriceVersionID;
}
public partial class Product : IPrimaryKeyEntity<ProductPrimaryKey>,
INotifyPropertyChanging, INotifyPropertyChanged
{
#region IPrimaryKeyEntity Implementation
public ProductPrimaryKey PrimaryKey
{
get
{ return new ProductPrimaryKey()
{
ProductID = this.ProductID,
ProductPriceVersionID = this.ProductPriceVersionID
};
}
}
#endregion
...
//Rest is mostly standard LinqToSql entity generation
}
Возвращаясь к исходной цели, теперь я могу скомпилировать следующее для всех моих первичных ключевых сущностей:
from oldEntity in oldTableOrCollection
join newEntity in newTableOrCollection
on oldEntity.PrimaryKey equals newEntity.PrimaryKey
select new {oldEntity, newEntity}
Однако, во время выполнения, я получаю печально известное исключение [PrimaryKey] "не поддерживает перевод в SQL".
Я понимаю, что для перевода на SQL необходимо использовать Expression
, однако я довольно незнаком с Linq.Expressions
и пока не достиг прогресса, пытаясь применить его к моей ситуации ...
Если кто-то может улучшить то, что у меня есть, или у него есть лучший метод в целом, я был бы рад узнать ....
Приветствия