我有這個問題,我真的不知道如何解決它。在提出這個問題之前,我問了兩個問題,但沒有得到我的情況的正確答案。這是詳細的問題。 我有一個接口,默認的實現:將一個方法轉換爲實體表達式以查詢實體框架
public interface IEntityPriceDefinition
{
PriceDefinition PriceDefinition { get; }
bool IsMatch(long additionId);
bool IsMatch(long? entityId, long? inviterId, long? routeId, long? luggageTypeId);
bool IsMatch(long? entityId, long? inviterId, long? routeId, long? luggageTypeId,
long additionId);
bool IsMatch(long? entityId, Task3 task);
bool IsMatch(long? entityId, Task3 task, long additionId);
}
public class EntityPriceDefinition : IEntityPriceDefinition
{
private PriceDefinition _PriceDefinition;
private Func<long?, bool> _IsEntityIdMatch;
private Func<Task3, long?> _TaskValue;
public PriceDefinition PriceDefinition { get { return _PriceDefinition; } }
internal EntityPriceDefinition(
PriceDefinition priceDefinition,
Func<long?, bool> isEntityIdMatch,
Func<Task3, long?> taskValue)
{
_PriceDefinition = priceDefinition;
_IsEntityIdMatch = isEntityIdMatch;
_TaskValue = taskValue;
}
public bool IsMatch(long additionId)
{
return PriceDefinition.AdditionsPrices.Any(x => x.AdditionId == additionId);
}
private bool IsMatch(long? inviterId, long? routeId, long? luggageTypeId)
{
bool isMatch = inviterId.HasValue || routeId.HasValue || luggageTypeId.HasValue;
if (isMatch)
{
if (PriceDefinition.InviterId.HasValue && inviterId.HasValue)
{
if (PriceDefinition.InviterId.Value != inviterId.Value) { isMatch = false; }
}
if (PriceDefinition.LuggageTypeId.HasValue && luggageTypeId.HasValue)
{
if (PriceDefinition.LuggageTypeId.Value != luggageTypeId.Value) { isMatch = false; }
}
if (PriceDefinition.RouteId.HasValue && routeId.HasValue)
{
if (PriceDefinition.RouteId.Value != routeId.Value) { isMatch = false; }
}
}
return isMatch;
}
public bool IsMatch(long? entityId, long? inviterId, long? routeId, long? luggageTypeId)
{
return _IsEntityIdMatch(entityId) && IsMatch(inviterId, routeId, luggageTypeId);
}
public bool IsMatch(long? entityId, long? inviterId, long? routeId, long? luggageTypeId,
long additionId)
{
return IsMatch(entityId, inviterId, routeId, luggageTypeId) && IsMatch(additionId);
}
public bool IsMatch(long? entityId, Task3 task)
{
bool isMatch = _IsEntityIdMatch(_TaskValue(task)) &&
IsMatch(task.InviterId, task.RouteId, task.LuggageTypeId);
for (int i = 0; i < PriceDefinition.Rules.Count && isMatch == true; i++)
{
object value = task.GetFieldObjectValue(PriceDefinition.Rules[i].FieldName);
isMatch = PriceDefinition.Rules[i].IsMatch((value ?? string.Empty).ToString());
}
return isMatch;
}
public bool IsMatch(long? entityId, Task3 task, long additionId)
{
return IsMatch(entityId ,task) && IsMatch(additionId);
}
}
我也有3類使用默認的實現,實現IEntityPriceDefinition
。這裏有兩個那些類的(第三個是相同的):
public class CustomerPriceDefinition : IEntityPriceDefinition, IDataEntity
{
private IEntityPriceDefinition _EntityPriceDefinition;
public virtual long PriceDefinitionId { get; set; }
public virtual long CustomerId { get; set; }
public virtual PriceDefinition PriceDefinition { get; set; }
public CustomerPriceDefinition()
{
_EntityPriceDefinition = new EntityPriceDefinition(
PriceDefinition,
entityId => entityId.HasValue && entityId.Value == CustomerId,
t => t.CustomerId);
}
public bool IsMatch(long additionId)
{
return _EntityPriceDefinition.IsMatch(additionId);
}
public bool IsMatch(long? customerId, long? inviterId, long? routeId, long? luggageTypeId)
{
return _EntityPriceDefinition.IsMatch(customerId, inviterId, routeId, luggageTypeId);
}
public bool IsMatch(long? customerId, long? inviterId, long? routeId, long? luggageTypeId,
long additionId)
{
return _EntityPriceDefinition.IsMatch(customerId, inviterId, routeId, luggageTypeId,
additionId);
}
public bool IsMatch(long? customerId, Task3 task)
{
return _EntityPriceDefinition.IsMatch(customerId, task);
}
public bool IsMatch(long? customerId, Task3 task, long additionId)
{
return _EntityPriceDefinition.IsMatch(customerId, task, additionId);
}
}
public class WorkerPriceDefinition : IEntityPriceDefinition, IDataEntity
{
private IEntityPriceDefinition _EntityPriceDefinition;
public virtual long PriceDefinitionId { get; set; }
public virtual long WorkerId { get; set; }
public virtual PriceDefinition PriceDefinition { get; set; }
public WorkerPriceDefinition()
{
_EntityPriceDefinition = new EntityPriceDefinition(
PriceDefinition,
entityId => entityId.HasValue && entityId.Value == WorkerId,
t => t.WorkerId);
}
public bool IsMatch(long additionId)
{
return _EntityPriceDefinition.IsMatch(additionId);
}
public bool IsMatch(long? workerId, long? inviterId, long? routeId, long? luggageTypeId)
{
return _EntityPriceDefinition.IsMatch(workerId, inviterId, routeId, luggageTypeId);
}
public bool IsMatch(long? workerId, long? inviterId, long? routeId, long? luggageTypeId,
long additionId)
{
return _EntityPriceDefinition.IsMatch(workerId, inviterId, routeId, luggageTypeId,
additionId);
}
public bool IsMatch(long? workerId, Task3 task)
{
return _EntityPriceDefinition.IsMatch(workerId, task);
}
public bool IsMatch(long? workerId, Task3 task, long additionId)
{
return _EntityPriceDefinition.IsMatch(workerId, task, additionId);
}
}
我也有倉庫接口和默認實現這些類:
public interface IEntityPriceDefinitionRepository<T> : IRepository<T>
where T : class, IEntityPriceDefinition, IDataEntity
{
IEnumerable<T> GetMatchPrices(
Guid companyId, bool? isSuggested, bool? isValid,
long? entityId, long? inviterId, long? routeId, long? luggageTypeId,
Func<IQueryable<T>, IOrderedQueryable<T>> orderBy,
Expression<Func<T, object>>[] includes);
IEnumerable<T> GetMatchPrices(
Guid companyId, bool? isSuggested, bool? isValid,
long? entityId, long? inviterId, long? routeId, long? luggageTypeId, long additionId,
Func<IQueryable<T>, IOrderedQueryable<T>> orderBy,
Expression<Func<T, object>>[] includes);
}
public class EntityPriceDefinitionRepository<T> : BaseRepository<T>,
IEntityPriceDefinitionRepository<T> where T : class,IEntityPriceDefinition, IDataEntity
{
private IEnumerable<T> GetMatchPrices(
Guid companyId, bool? isSuggested, bool? isValid,
Expression<Func<T, bool>> isMatch,
Func<IQueryable<T>, IOrderedQueryable<T>> orderBy,
Expression<Func<T, object>>[] includes)
{
var filters = new Expression<Func<T, bool>>[]{
x => x.PriceDefinition.CompanyId == companyId,
x => x.PriceDefinition.IsDeleted == false,
x => !isValid.HasValue || x.PriceDefinition.IsValid == isValid.Value,
x => !isSuggested.HasValue || x.PriceDefinition.IsSuggested == isSuggested.Value,
isMatch
};
return GetQuery(filters, orderBy, includes);
}
public IEnumerable<T> GetMatchPrices(
Guid companyId, bool? isSuggested, bool? isValid,
long? entityId, long? inviterId, long? routeId, long? luggageTypeId,
Func<IQueryable<T>, IOrderedQueryable<T>> orderBy,
Expression<Func<T, object>>[] includes)
{
return GetMatchPrices(companyId, isSuggested, isValid,
////////////////// THIS CAUSE THE EXCEPTION MENTIONED BELOW: //////////////////
x => x.IsMatch(entityId, inviterId, routeId, luggageTypeId),
orderBy, includes);
}
public IEnumerable<T> GetMatchPrices(
Guid companyId, bool? isSuggested, bool? isValid,
long? entityId, long? inviterId, long? routeId, long? luggageTypeId, long additionId,
Func<IQueryable<T>, IOrderedQueryable<T>> orderBy,
Expression<Func<T, object>>[] includes)
{
return GetMatchPrices(companyId, isSuggested, isValid,
////////////////// THIS CAUSE THE EXCEPTION MENTIONED BELOW: //////////////////
x => x.IsMatch(entityId, inviterId, routeId, luggageTypeId, additionId),
orderBy, includes);
}
}
及其類別庫類只是:
public class CustomerPriceDefinitionRepository :
EntityPriceDefinitionRepository<CustomerPriceDefinition> { }
public class WorkerPriceDefinitionRepository :
EntityPriceDefinitionRepository<WorkerPriceDefinition> { }
當我調用CustomerPriceDefinitionRepository的GetMatchPrices方法時,會出現問題。它總是以有關上述標記方法異常結束:
LINQ實體無法識別方法「布爾IsMatch(System.Nullable
1[System.Int64], System.Nullable
1 [System.Int64],System.Nullable1[System.Int64], System.Nullable
1 [系統。 Int64])'方法,並且此方法不能轉換爲商店表達式。
拉吉斯拉夫Mrnka的回答我here使用模型中定義的功能,但我想我所有的代碼是在它的類,而不是在XML的。另外,這段代碼與edmx使用的巨大範圍無關。此外,我相信爲了使用模型定義的函數,我將不得不定義3個方法 - 每個IEntityPriceDefinition子類的一個IsMatch。
我真的不知道如何解決這個問題,這種情況下最好的解決方案是什麼,特別是對於這樣的非簡單結構。我會appriciate任何幫助。
正如其他許多人已經告訴你的,問題是'.IsMatch'沒有SQL等價物,因此**不能被**轉換成Linq-to-Entities的有效SQL語句。所以你需要找到另一種表達這種情況的方式,例如使用'.StartsWith()'或其他東西。 ** OR:**您需要從數據庫中檢索沒有該表達式的所有實體,並且只使用Linq-to-objects過濾應用內存中的這些實體。 – 2011-05-02 05:17:03
@marc_s:我明白了這個問題,我正在尋找解決問題的最佳方法。八,現在我不知道該怎麼做。 – Naor 2011-05-02 09:17:38
如果您正在使用SQL Server,是否可以將IsMatch作爲SQLCLR函數編寫,然後將其用作edmx的導入函數? – Menahem 2011-05-02 12:45:10