score:-1
This may work for you, but has the downside of needing to retrieve the full list of entities and loop through them to look for a match. You can specify the entity and property as arguments to the attribute.
public class UniqueAttribute : ValidationAttribute
{
public UniqueAttribute(Type entityType, string propertyName)
{
_entityType = entityType;
_propertyName = propertyName;
}
private Type _entityType;
private string _propertyName;
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
Context db = new Context();
foreach (var item in db.Set(_entityType).ToList())
{
if (value.Equals(GetPropertyValue(item, _propertyName))
{
return new ValidationResult(validationContext.DisplayName + " is already taken.");
}
}
return null;
}
private object GetPropertyValue(object item, string propertyName)
{
var type = item.GetType();
var propInfo = type.GetProperty(propertyName);
return (propInfo != null) ? propInfo.GetValue(value, null) : null;
}
}
}
Usage:
[Unique(typeof(User), "Login")]
public string Login { get; set; }
score:1
This will work. You need to build the expression tree manually.
Usage
Expression<Func<User, string>> userExp = x => x.Login;
UniqueAttribute u = new UniqueAttribute(userExp);`
EDIT: Removed generics to work w/ Attribute
. You need to use reflection w/ the runtime types to get the appropriate SingleOrDefault
method. Please note there is no compile time type checking on your expressions with this code. You should always declare the expression first (the way I did in the usage sample) to avoid type problems.
public class UniqueAttribute
{
private LambdaExpression Selector { get; set; }
private Type EntityType { get; set; }
public UniqueAttribute(LambdaExpression selector) {
this.EntityType = selector.Parameters[0].Type;
this.Selector = selector;
}
private LambdaExpression GeneratePredicate(object value) {
ParameterExpression param = Selector.Parameters[0];
Expression property = Selector.Body;
Expression valueConst = Expression.Constant(value);
Expression eq = Expression.Equal(property, valueConst);
LambdaExpression predicate = Expression.Lambda(eq, new ParameterExpression[]{param});
return predicate;
}
private TEntity SingleOrDefault<TEntity>(IQueryable<TEntity> set, LambdaExpression predicate) {
Type queryableType = typeof(Queryable);
IEnumerable<MethodInfo> allSodAccessors = queryableType.GetMethods(BindingFlags.Static | BindingFlags.Public).Where(x => x.Name=="SingleOrDefault");
MethodInfo twoArgSodAccessor = allSodAccessors.Single(x => x.GetParameters().Length == 2);
MethodInfo withGenArgs = twoArgSodAccessor.MakeGenericMethod(new []{typeof(TEntity)});
return (TEntity) withGenArgs.Invoke(null, new object[]{set, predicate});
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
Context db = new Context();
if (SingleOrDefault(db.Set(EntityType), GeneratePredicate(value)) != null)
{
return new ValidationResult(validationContext.DisplayName + " is already taken.");
}
return null;
}
}
Source: stackoverflow.com
Related Query
- Generic ValidationAttribute with dynamic Entity.Property unique check (set at run time)
- Entity Framework dynamic linq where from generic source with dynamic where clause
- How to make a property unique in Entity Framework Code First
- LINQ: Dynamic where with generic property and value
- How to Create a generic method with 1 known property. Want to dynamic get the properties in different class with Generic Class property
- How can I get only records with a unique property using entity framework and linq?
- Dynamic query with OR conditions in Entity Framework
- Creating dynamic queries with entity framework
- Dynamic linq order by on nested property with null properties
- Simple check to see if at least one object in a set has a property value of TRUE
- Getting unique values from a list of objects with a List<string> as a property
- Entity Framework 6 deep copy/clone of an entity with dynamic depth
- Eager load ALL by default with Entity Framework within a Generic Repository
- C# Create object with dynamic properties : LINQ select List<object> values by property names array
- Generic method to set the value of a property using expressions/lambda
- Create Generic Type with Generic Interface at Run Time
- C# Code Contracts -- How to ensure that a collection of items contains items with unique properties?
- Set value of property in IQueryable<T> after join with another table based on some conditions
- Can I check a property on a generic object by passing in a lambda expression to get the parameter?
- WhereIn with dynamic property
- How to get Multiple Result Set in Entity Framework using Linq with C#?
- LINQ expression with generic property
- How can I count number of objects in a list with a unique property with linq/lambda?
- Using Func property selector with Entity Framework 6
- How to get list of an entity with generic search
- Check if List<T> element contains an item with a Particular Property Value
- Same SQL query when run with sp_executesql is fast, very slow if executed as dynamic query in query analyser, why?
- Dynamic query building with entity framework core - Build a query "by steps"
- Creating Dynamic Search Queries with Entity Framework Web API using passed in parameters as the search fields
- Entity Framework and grouping by weeks with week start day set
More Query from same tag
- How to get DropDownList text from selected value via Linq
- Split an IEnumerable into multiple IEnumerables
- Linq to XML treating results individually instead of listing
- Doubts about deferred execution
- LinQ: Multiple joins with multiple columns identifiers
- How to create a view using EF code-first POCO
- How to group by day of week using linq
- LINQ Query (Group BY)?
- Linq: select property collection
- Return a List<SomeObject> without a certain property using Linq in c#?
- Linq to SQL - Getting the last know history entry for each divice, prior to a certain date
- linq datetime not contain max or min
- Dictionary look up where we want the keys contained in a string
- how to compare two complex object without case sensitive in linq
- NTILE function equivalent in C#
- How to create a list of one object attributes from the actual list of objects?
- Return Type for Collection from LINQ Query
- C# group by list then SUM
- use linq to get a sub list that contains elements from an array
- Modify List<T> using Linq to Average rows with matching designator
- Create a hierarchical JSON Http response structure using LinQ
- How can I speed up this linq query on a List<> with search criteria on 3 attributes in the list object
- Datatable Grouping Using Linq and VB .NET
- How to get rows of Data from Multiple Tables using LinQ To Entities
- Checking if a list is empty with LINQ
- How to validate that 4 fields are not repeated in any manner
- Find value via property name in json.net?
- LINQ OR operator not giving result
- DateTime comparison without time part?
- Bundle .NET 3.5 libs with app, so it runs on machines with only .NET 2.0 installed?